(main): use getarg
(*): handle v4 and/or v5 git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@6183 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		
							
								
								
									
										411
									
								
								appl/kx/kx.c
									
									
									
									
									
								
							
							
						
						
									
										411
									
								
								appl/kx/kx.c
									
									
									
									
									
								
							| @@ -97,39 +97,34 @@ usr2handler (int sig) | ||||
|  */ | ||||
|  | ||||
| static int | ||||
| connect_host (char *host, char *user, des_cblock *key, | ||||
| 	      des_key_schedule schedule, int port, | ||||
| 	      struct sockaddr_in *thisaddr, | ||||
| 	      struct sockaddr_in *thataddr) | ||||
| connect_host (kx_context *kc) | ||||
| { | ||||
|      CREDENTIALS cred; | ||||
|      KTEXT_ST text; | ||||
|      MSG_DAT msg; | ||||
|      int status; | ||||
|      int addrlen; | ||||
|      struct hostent *hostent; | ||||
|      int s; | ||||
|      char **p; | ||||
|      struct sockaddr_in thisaddr; | ||||
|      struct sockaddr_in thataddr; | ||||
|  | ||||
|      hostent = gethostbyname (host); | ||||
|      hostent = gethostbyname (kc->host); | ||||
|      if (hostent == NULL) { | ||||
| 	 warnx ("gethostbyname '%s' failed: %s", host, | ||||
| 	 warnx ("gethostbyname '%s' failed: %s", kc->host, | ||||
| 		hstrerror(h_errno)); | ||||
| 	 return -1; | ||||
|      } | ||||
|  | ||||
|      memset (thataddr, 0, sizeof(*thataddr)); | ||||
|      thataddr->sin_family = AF_INET; | ||||
|      thataddr->sin_port   = port; | ||||
|      memset (&thataddr, 0, sizeof(thataddr)); | ||||
|      thataddr.sin_family = AF_INET; | ||||
|      thataddr.sin_port   = kc->port; | ||||
|      for(p = hostent->h_addr_list; *p; ++p) { | ||||
| 	 memcpy (&thataddr->sin_addr, *p, sizeof(thataddr->sin_addr)); | ||||
| 	 memcpy (&thataddr.sin_addr, *p, sizeof(thataddr.sin_addr)); | ||||
|  | ||||
| 	 s = socket (AF_INET, SOCK_STREAM, 0); | ||||
| 	 if (s < 0) | ||||
| 	     err (1, "socket"); | ||||
|  | ||||
| 	 if (connect (s, (struct sockaddr *)thataddr, sizeof(*thataddr)) < 0) { | ||||
| 	     warn ("connect(%s)", host); | ||||
| 	 if (connect (s, (struct sockaddr *)&thataddr, sizeof(thataddr)) < 0) { | ||||
| 	     warn ("connect(%s)", kc->host); | ||||
| 	     close (s); | ||||
| 	     continue; | ||||
| 	 } else { | ||||
| @@ -139,19 +134,14 @@ connect_host (char *host, char *user, des_cblock *key, | ||||
|      if (*p == NULL) | ||||
| 	 return -1; | ||||
|  | ||||
|      addrlen = sizeof(*thisaddr); | ||||
|      if (getsockname (s, (struct sockaddr *)thisaddr, &addrlen) < 0 || | ||||
| 	 addrlen != sizeof(*thisaddr)) | ||||
| 	 err(1, "getsockname(%s)", host); | ||||
|      status = krb_sendauth (KOPT_DO_MUTUAL, s, &text, "rcmd", | ||||
| 			    host, krb_realmofhost (host), | ||||
| 			    getpid(), &msg, &cred, schedule, | ||||
| 			    thisaddr, thataddr, KX_VERSION); | ||||
|      if (status != KSUCCESS) { | ||||
| 	 warnx ("%s: %s\n", host, krb_get_err_text(status)); | ||||
|      addrlen = sizeof(thisaddr); | ||||
|      if (getsockname (s, (struct sockaddr *)&thisaddr, &addrlen) < 0 || | ||||
| 	 addrlen != sizeof(thisaddr)) | ||||
| 	 err(1, "getsockname(%s)", kc->host); | ||||
|      kc->thisaddr = thisaddr; | ||||
|      kc->thataddr = thataddr; | ||||
|      if ((*kc->authenticate)(kc, s)) | ||||
| 	 return -1; | ||||
|      } | ||||
|      memcpy(key, cred.session, sizeof(des_cblock)); | ||||
|      return s; | ||||
| } | ||||
|  | ||||
| @@ -161,23 +151,21 @@ connect_host (char *host, char *user, des_cblock *key, | ||||
|  */ | ||||
|  | ||||
| static int | ||||
| passive_session (int xserver, int fd, des_cblock *iv, | ||||
| 		 des_key_schedule schedule) | ||||
| passive_session (int xserver, int fd, kx_context *kc) | ||||
| { | ||||
|     if (replace_cookie (xserver, fd, XauFileName(), 1)) | ||||
| 	return 1; | ||||
|     else | ||||
| 	return copy_encrypted (xserver, fd, iv, schedule); | ||||
| 	return copy_encrypted (kc, xserver, fd); | ||||
| } | ||||
|  | ||||
| static int | ||||
| active_session (int xserver, int fd, des_cblock *iv, | ||||
| 		des_key_schedule schedule) | ||||
| active_session (int xserver, int fd, kx_context *kc) | ||||
| { | ||||
|     if (verify_and_remove_cookies (xserver, fd, 1)) | ||||
| 	return 1; | ||||
|     else | ||||
| 	return copy_encrypted (xserver, fd, iv, schedule); | ||||
| 	return copy_encrypted (kc, xserver, fd); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -208,24 +196,20 @@ status_output (int debugp) | ||||
|  */ | ||||
|  | ||||
| static int | ||||
| doit_passive (char *host, char *user, int debugp, int keepalivep, | ||||
| 	      int port) | ||||
| doit_passive (kx_context *kc) | ||||
| { | ||||
|      des_key_schedule schedule; | ||||
|      des_cblock key; | ||||
|      int otherside; | ||||
|      struct sockaddr_in me, him; | ||||
|      u_char msg[1024], *p; | ||||
|      int len; | ||||
|      void *ret; | ||||
|      u_int32_t tmp; | ||||
|      char *host = kc->host; | ||||
|  | ||||
|      otherside = connect_host (kc); | ||||
|  | ||||
|      otherside = connect_host (host, user, &key, schedule, port, | ||||
| 			       &me, &him); | ||||
|      if (otherside < 0) | ||||
| 	 return 1; | ||||
| #if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT) | ||||
|      if (keepalivep) { | ||||
|      if (kc->keepalive_flag) { | ||||
| 	 int one = 1; | ||||
|  | ||||
| 	 setsockopt (otherside, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, | ||||
| @@ -235,22 +219,20 @@ doit_passive (char *host, char *user, int debugp, int keepalivep, | ||||
|  | ||||
|      p = msg; | ||||
|      *p++ = INIT; | ||||
|      len = strlen(user); | ||||
|      p += krb_put_int (len, p, sizeof(msg) - 1, 4); | ||||
|      memcpy(p, user, len); | ||||
|      len = strlen(kc->user); | ||||
|      p += KRB_PUT_INT (len, p, sizeof(msg) - 1, 4); | ||||
|      memcpy(p, kc->user, len); | ||||
|      p += len; | ||||
|      *p++ = PASSIVE | (keepalivep ? KEEP_ALIVE : 0); | ||||
|      if (write_encrypted (otherside, msg, p - msg, schedule, | ||||
| 			  &key, &me, &him) < 0) | ||||
|      *p++ = PASSIVE | (kc->keepalive_flag ? KEEP_ALIVE : 0); | ||||
|      if (kx_write (kc, otherside, msg, p - msg) != p - msg) | ||||
| 	 err (1, "write to %s", host); | ||||
|      len = read_encrypted (otherside, msg, sizeof(msg), &ret, | ||||
| 			   schedule, &key, &him, &me); | ||||
|      len = kx_read (kc, otherside, msg, sizeof(msg)); | ||||
|      if (len <= 0) | ||||
| 	 errx (1, | ||||
| 	       "error reading initial message from %s: " | ||||
| 	       "this probably means it's using an old version.", | ||||
| 	       host); | ||||
|      p = (u_char *)ret; | ||||
|      p = (u_char *)msg; | ||||
|      if (*p == ERROR) { | ||||
| 	 p++; | ||||
| 	 p += krb_get_int (p, &tmp, 4, 0); | ||||
| @@ -269,18 +251,17 @@ doit_passive (char *host, char *user, int debugp, int keepalivep, | ||||
|      xauthfile[tmp] = '\0'; | ||||
|      p += tmp; | ||||
|  | ||||
|      status_output (debugp); | ||||
|      status_output (kc->debug_flag); | ||||
|      for (;;) { | ||||
| 	 pid_t child; | ||||
|  | ||||
| 	 len = read_encrypted (otherside, msg, sizeof(msg), &ret, | ||||
| 			       schedule, &key, &him, &me); | ||||
| 	 len = kx_read (kc, otherside, msg, sizeof(msg)); | ||||
| 	 if (len < 0) | ||||
| 	     err (1, "read from %s", host); | ||||
| 	 else if (len == 0) | ||||
| 	     return 0; | ||||
|  | ||||
| 	 p = (u_char *)ret; | ||||
| 	 p = (u_char *)msg; | ||||
| 	 if (*p == ERROR) { | ||||
| 	     p++; | ||||
| 	     p += krb_get_int (p, &tmp, 4, 0); | ||||
| @@ -302,7 +283,7 @@ doit_passive (char *host, char *user, int debugp, int keepalivep, | ||||
| 	     int fd; | ||||
| 	     int xserver; | ||||
|  | ||||
| 	     addr = him; | ||||
| 	     addr = kc->thataddr; | ||||
| 	     close (otherside); | ||||
|  | ||||
| 	     addr.sin_port = htons(tmp); | ||||
| @@ -318,7 +299,7 @@ doit_passive (char *host, char *user, int debugp, int keepalivep, | ||||
| 	     } | ||||
| #endif | ||||
| #if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT) | ||||
| 	     if (keepalivep) { | ||||
| 	     if (kc->keepalive_flag) { | ||||
| 		 int one = 1; | ||||
|  | ||||
| 		 setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, | ||||
| @@ -343,7 +324,7 @@ doit_passive (char *host, char *user, int debugp, int keepalivep, | ||||
| 		 if (xserver < 0) | ||||
| 		     return 1; | ||||
| 	     } | ||||
| 	     return passive_session (xserver, fd, &key, schedule); | ||||
| 	     return passive_session (xserver, fd, kc); | ||||
| 	 } else { | ||||
| 	 } | ||||
|      } | ||||
| @@ -354,31 +335,26 @@ doit_passive (char *host, char *user, int debugp, int keepalivep, | ||||
|  */ | ||||
|  | ||||
| static int | ||||
| doit_active (char *host, char *user, | ||||
| 	     int debugpp, int keepalivep, int tcpp, int port) | ||||
| doit_active (kx_context *kc) | ||||
| { | ||||
|     des_key_schedule schedule; | ||||
|     des_cblock key; | ||||
|     int otherside; | ||||
|     int nsockets; | ||||
|     struct x_socket *sockets; | ||||
|     struct sockaddr_in me, him; | ||||
|     u_char msg[1024], *p; | ||||
|     int len = strlen(user); | ||||
|     void *ret; | ||||
|     int len = strlen(kc->user); | ||||
|     int tmp, tmp2; | ||||
|     char *s; | ||||
|     int i; | ||||
|     size_t rem; | ||||
|     u_int32_t other_port; | ||||
|     int error; | ||||
|     char *host = kc->host; | ||||
|  | ||||
|     otherside = connect_host (host, user, &key, schedule, port, | ||||
| 			      &me, &him); | ||||
|     otherside = connect_host (kc); | ||||
|     if (otherside < 0) | ||||
| 	return 1; | ||||
| #if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT) | ||||
|     if (keepalivep) { | ||||
|     if (kc->keepalive_flag) { | ||||
| 	int one = 1; | ||||
|  | ||||
| 	setsockopt (otherside, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, | ||||
| @@ -389,23 +365,23 @@ doit_active (char *host, char *user, | ||||
|     rem = sizeof(msg); | ||||
|     *p++ = INIT; | ||||
|     --rem; | ||||
|     len = strlen(user); | ||||
|     tmp = krb_put_int (len, p, rem, 4); | ||||
|     len = strlen(kc->user); | ||||
|     tmp = KRB_PUT_INT (len, p, rem, 4); | ||||
|     if (tmp < 0) | ||||
| 	return 1; | ||||
|     p += tmp; | ||||
|     rem -= tmp; | ||||
|     memcpy(p, user, len); | ||||
|     memcpy(p, kc->user, len); | ||||
|     p += len; | ||||
|     rem -= len; | ||||
|     *p++ = (keepalivep ? KEEP_ALIVE : 0); | ||||
|     *p++ = (kc->keepalive_flag ? KEEP_ALIVE : 0); | ||||
|     --rem; | ||||
|  | ||||
|     s = getenv("DISPLAY"); | ||||
|     if (s == NULL || (s = strchr(s, ':')) == NULL)  | ||||
| 	s = ":0"; | ||||
|     len = strlen (s); | ||||
|     tmp = krb_put_int (len, p, rem, 4); | ||||
|     tmp = KRB_PUT_INT (len, p, rem, 4); | ||||
|     if (tmp < 0) | ||||
| 	return 1; | ||||
|     rem -= tmp; | ||||
| @@ -418,7 +394,7 @@ doit_active (char *host, char *user, | ||||
|     if (s == NULL) | ||||
| 	s = ""; | ||||
|     len = strlen (s); | ||||
|     tmp = krb_put_int (len, p, rem, 4); | ||||
|     tmp = KRB_PUT_INT (len, p, rem, 4); | ||||
|     if (tmp < 0) | ||||
| 	return 1; | ||||
|     p += len; | ||||
| @@ -427,15 +403,13 @@ doit_active (char *host, char *user, | ||||
|     p += len; | ||||
|     rem -= len; | ||||
|  | ||||
|     if (write_encrypted (otherside, msg, p - msg, schedule, | ||||
| 			 &key, &me, &him) < 0) | ||||
|     if (kx_write (kc, otherside, msg, p - msg) != p - msg) | ||||
| 	err (1, "write to %s", host); | ||||
|  | ||||
|     len = read_encrypted (otherside, msg, sizeof(msg), &ret, | ||||
| 			  schedule, &key, &him, &me); | ||||
|     len = kx_read (kc, otherside, msg, sizeof(msg)); | ||||
|     if (len < 0) | ||||
| 	err (1, "read from %s", host); | ||||
|     p = (u_char *)ret; | ||||
|     p = (u_char *)msg; | ||||
|     if (*p == ERROR) { | ||||
| 	u_int32_t u32; | ||||
|  | ||||
| @@ -447,11 +421,11 @@ doit_active (char *host, char *user, | ||||
|     } else | ||||
| 	p++; | ||||
|  | ||||
|     tmp2 = get_xsockets (&nsockets, &sockets, tcpp); | ||||
|     tmp2 = get_xsockets (&nsockets, &sockets, kc->tcp_flag); | ||||
|     if (tmp2 < 0) | ||||
| 	return 1; | ||||
|     display_num = tmp2; | ||||
|     if (tcpp) | ||||
|     if (kc->tcp_flag) | ||||
| 	snprintf (display, display_size, "localhost:%u", display_num); | ||||
|     else | ||||
| 	snprintf (display, display_size, ":%u", display_num); | ||||
| @@ -461,7 +435,7 @@ doit_active (char *host, char *user, | ||||
| 	warnx ("failed creating cookie file: %s", strerror(error)); | ||||
| 	return 1; | ||||
|     } | ||||
|     status_output (debugpp); | ||||
|     status_output (kc->debug_flag); | ||||
|     for (;;) { | ||||
| 	fd_set fdset; | ||||
| 	pid_t child; | ||||
| @@ -488,14 +462,12 @@ doit_active (char *host, char *user, | ||||
|  | ||||
| 	p = msg; | ||||
| 	*p++ = NEW_CONN; | ||||
| 	if (write_encrypted (otherside, msg, p - msg, schedule, | ||||
| 			     &key, &me, &him) < 0) | ||||
| 	if (kx_write (kc, otherside, msg, p - msg) != p - msg) | ||||
| 	    err (1, "write to %s", host); | ||||
| 	len = read_encrypted (otherside, msg, sizeof(msg), &ret, | ||||
| 			      schedule, &key, &him, &me); | ||||
| 	len = kx_read (kc, otherside, msg, sizeof(msg)); | ||||
| 	if (len < 0) | ||||
| 	    err (1, "read from %s", host); | ||||
| 	p = (u_char *)ret; | ||||
| 	p = (u_char *)msg; | ||||
| 	if (*p == ERROR) { | ||||
| 	    u_int32_t val; | ||||
|  | ||||
| @@ -521,7 +493,7 @@ doit_active (char *host, char *user, | ||||
| 	    for (i = 0; i < nsockets; ++i) | ||||
| 		close (sockets[i].fd); | ||||
|  | ||||
| 	    addr = him; | ||||
| 	    addr = kc->thataddr; | ||||
| 	    close (otherside); | ||||
|  | ||||
| 	    addr.sin_port = htons(other_port); | ||||
| @@ -537,7 +509,7 @@ doit_active (char *host, char *user, | ||||
| 	    } | ||||
| #endif | ||||
| #if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT) | ||||
| 	    if (keepalivep) { | ||||
| 	    if (kc->keepalive_flag) { | ||||
| 		int one = 1; | ||||
|  | ||||
| 		setsockopt (s, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, | ||||
| @@ -548,7 +520,7 @@ doit_active (char *host, char *user, | ||||
| 	    if (connect (s, (struct sockaddr *)&addr, sizeof(addr)) < 0) | ||||
| 		err(1, "connect"); | ||||
|  | ||||
| 	    return active_session (fd, s, &key, schedule); | ||||
| 	    return active_session (fd, s, kc); | ||||
| 	} else { | ||||
| 	    close (fd); | ||||
| 	} | ||||
| @@ -573,79 +545,212 @@ check_for_passive (const char *disp) | ||||
| 	 || strncmp(disp, local_hostname, strlen(local_hostname)) == 0); | ||||
| } | ||||
|  | ||||
| static void | ||||
| usage(void) | ||||
| static int | ||||
| doit (kx_context *kc, int passive_flag) | ||||
| { | ||||
|     fprintf(stderr, "Usage: %s [-p port] [-d] [-D] [-t] [-l remoteuser] host\n", | ||||
| 	    __progname); | ||||
|     exit (1); | ||||
|     signal (SIGCHLD, childhandler); | ||||
|     signal (SIGUSR1, usr1handler); | ||||
|     signal (SIGUSR2, usr2handler); | ||||
|     if (passive_flag) | ||||
| 	return doit_passive (kc); | ||||
|     else | ||||
| 	return doit_active  (kc); | ||||
| } | ||||
|  | ||||
| #ifdef KRB4 | ||||
| static int | ||||
| doit_v4 (char *host, int port, char *user,  | ||||
| 	 int passive_flag, int debug_flag, int keepalive_flag, int tcp_flag) | ||||
| { | ||||
|     int ret; | ||||
|     kx_context context; | ||||
|  | ||||
|     krb4_make_context (&context); | ||||
|     context_set (&context, | ||||
| 		 host, user, port, debug_flag, keepalive_flag, tcp_flag); | ||||
|  | ||||
|     ret = doit (&context, passive_flag); | ||||
|     context_destroy (&context); | ||||
|     return ret; | ||||
| } | ||||
| #endif /* KRB4 */ | ||||
|  | ||||
| #ifdef KRB5 | ||||
|  | ||||
| static int | ||||
| doit_v5 (char *host, int port, char *user, | ||||
| 	 int passive_flag, int debug_flag, int keepalive_flag, int tcp_flag) | ||||
| { | ||||
|     int ret; | ||||
|     kx_context context; | ||||
|  | ||||
|     krb5_make_context (&context); | ||||
|     context_set (&context, | ||||
| 		 host, user, port, debug_flag, keepalive_flag, tcp_flag); | ||||
|  | ||||
|     ret = doit (&context, passive_flag); | ||||
|     context_destroy (&context); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  *  | ||||
|  */ | ||||
|  | ||||
| #ifdef KRB4 | ||||
| static int use_v4		= 0; | ||||
| static int krb_debug_flag	= 0; | ||||
| #endif | ||||
| #ifdef KRB5 | ||||
| static int use_v5		= 0; | ||||
| static int forward_flag		= 0; | ||||
| static int forwardable_flag	= 0; | ||||
| #endif | ||||
| static char *port_str		= NULL; | ||||
| static char *user		= NULL; | ||||
| static int tcp_flag		= 0; | ||||
| static int passive_flag		= 0; | ||||
| static int keepalive_flag	= 1; | ||||
| static int debug_flag		= 0; | ||||
| static int version_flag		= 0; | ||||
| static int help_flag		= 0; | ||||
|  | ||||
| struct getargs args[] = { | ||||
| #ifdef KRB4 | ||||
|     { "krb4",	'4', arg_flag,		&use_v4,	"Use Kerberos V4", | ||||
|       NULL }, | ||||
|     { "krb4-debug", 'D', arg_flag,	&krb_debug_flag, | ||||
|       "enable krb4 debugging" }, | ||||
| #endif | ||||
| #ifdef KRB5 | ||||
|     { "krb5",	'5', arg_flag,		&use_v5,	"Use Kerberos V5", | ||||
|       NULL }, | ||||
|     { "forward", 'f', arg_flag,		&forward_flag,	"Forward credentials", | ||||
|       NULL }, | ||||
|     { "forwardable", 'F', arg_flag,	&forwardable_flag, | ||||
|       "Forward forwardable credentials", NULL }, | ||||
| #endif | ||||
|     { "port",	'p', arg_string,	&port_str,	"Use this port", | ||||
|       "number-of-service" }, | ||||
|     { "user",	'l', arg_string,	&user,		"Run as this user", | ||||
|       NULL }, | ||||
|     { "tcp",	't', arg_flag,		&tcp_flag, | ||||
|       "Use a TCP connection for X11" }, | ||||
|     { "passive", 'P', arg_flag,		&passive_flag, | ||||
|       "Force a passive connection" }, | ||||
|     { "keepalive", 'k', arg_negative_flag, &keepalive_flag, | ||||
|       "disable keep-alives" }, | ||||
|     { "debug",	'd',	arg_flag,	&debug_flag, | ||||
|       "Enable debug information" }, | ||||
|     { "version", 0,  arg_flag,		&version_flag,	"Print version", | ||||
|       NULL }, | ||||
|     { "help",	 0,  arg_flag,		&help_flag,	NULL, | ||||
|       NULL } | ||||
| }; | ||||
|  | ||||
| static void | ||||
| usage(int ret) | ||||
| { | ||||
|     arg_printusage (args, | ||||
| 		    sizeof(args) / sizeof(args[0]), | ||||
| 		    NULL, | ||||
| 		    "host"); | ||||
|     exit (ret); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * kx - forward x connection over a kerberos-encrypted channel. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| int | ||||
| main(int argc, char **argv) | ||||
| { | ||||
|      int force_passive = 0; | ||||
|      int keepalivep = 1; | ||||
|      char *user = NULL; | ||||
|      int debugp = 0, tcpp = 0; | ||||
|      int c; | ||||
|      int port = 0; | ||||
|     int port	= 0; | ||||
|     int optind	= 0; | ||||
|     int ret	= 1; | ||||
|     char *host	= NULL; | ||||
|  | ||||
|      set_progname (argv[0]); | ||||
|      while((c = getopt(argc, argv, "ktdDl:p:P")) != EOF) { | ||||
| 	 switch(c) { | ||||
| 	 case 'd' : | ||||
| 	     debugp = 1; | ||||
| 	     break; | ||||
| 	 case 'D': | ||||
| 	     krb_enable_debug(); | ||||
| 	     break; | ||||
| 	 case 'k': | ||||
| 	     keepalivep = 0; | ||||
| 	     break; | ||||
| 	 case 't' : | ||||
| 	     tcpp = 1; | ||||
| 	     break; | ||||
| 	 case 'l' : | ||||
| 	     user = optarg; | ||||
| 	     break; | ||||
| 	 case 'p' : | ||||
| 	     port = htons(atoi (optarg)); | ||||
| 	     break; | ||||
| 	 case 'P' : | ||||
| 	     force_passive = 1; | ||||
| 	     break; | ||||
| 	 case '?': | ||||
| 	 default: | ||||
| 	     usage(); | ||||
| 	 } | ||||
|      } | ||||
|     set_progname (argv[0]); | ||||
|  | ||||
|      argc -= optind; | ||||
|      argv += optind; | ||||
|     if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv, | ||||
| 		&optind)) | ||||
| 	usage (1); | ||||
|  | ||||
|      if (argc != 1) | ||||
| 	  usage (); | ||||
|      if (user == NULL) { | ||||
| 	  struct passwd *p = k_getpwuid (getuid ()); | ||||
| 	  if (p == NULL) | ||||
| 	      errx(1, "Who are you?"); | ||||
| 	  user = strdup (p->pw_name); | ||||
| 	  if (user == NULL) | ||||
| 	      errx (1, "strdup: out of memory"); | ||||
|      } | ||||
|      if (port == 0) | ||||
| 	 port = k_getportbyname ("kx", "tcp", htons(KX_PORT)); | ||||
|      signal (SIGCHLD, childhandler); | ||||
|      signal (SIGUSR1, usr1handler); | ||||
|      signal (SIGUSR2, usr2handler); | ||||
|      if (force_passive || check_for_passive(getenv("DISPLAY"))) | ||||
| 	 return doit_passive (argv[0], user, debugp, keepalivep, port); | ||||
|      else | ||||
| 	 return doit_active  (argv[0], user, debugp, keepalivep, tcpp, port); | ||||
|     if (help_flag) | ||||
| 	usage (0); | ||||
|  | ||||
|     if (version_flag) { | ||||
| 	print_version (NULL); | ||||
| 	return 0; | ||||
|     } | ||||
|  | ||||
|     if (optind != argc - 1) | ||||
| 	usage (1); | ||||
|  | ||||
|     if (forwardable_flag) | ||||
| 	forward_flag = 1; | ||||
|  | ||||
|     host = argv[optind]; | ||||
|  | ||||
|     if (port_str) { | ||||
| 	struct servent *s = roken_getservbyname (port_str, "tcp"); | ||||
|  | ||||
| 	if (s) | ||||
| 	    port = s->s_port; | ||||
| 	else { | ||||
| 	    char *ptr; | ||||
|  | ||||
| 	    port = strtol (port_str, &ptr, 10); | ||||
| 	    if (port == 0 && ptr == port_str) | ||||
| 		errx (1, "Bad port `%s'", port_str); | ||||
| 	    port = htons(port); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     if (user == NULL) { | ||||
| 	struct passwd *pwd = getpwuid (getuid ()); | ||||
|  | ||||
| 	if (pwd == NULL) | ||||
| 	    errx (1, "who are you?"); | ||||
| 	user = pwd->pw_name; | ||||
|     } | ||||
|  | ||||
|     if (!passive_flag) | ||||
| 	passive_flag = check_for_passive (getenv("DISPLAY")); | ||||
|  | ||||
| #ifdef KRB4 | ||||
|     if (krb_debug_flag) | ||||
| 	krb_enable_debug (); | ||||
| #endif | ||||
|  | ||||
| #if defined(KRB5) | ||||
| #if defined(KRB4) | ||||
|     if (use_v4 == 0 && use_v5 == 0) | ||||
| 	use_v5 = 1; | ||||
| #else | ||||
|     use_v5 = 1; | ||||
| #endif /* KRB4 */ | ||||
| #elif defined(KRB4) | ||||
|     use_v4 = 1; | ||||
| #endif | ||||
|  | ||||
| #ifdef KRB5 | ||||
|     if (ret && use_v5) { | ||||
| 	if (port == 0) | ||||
| 	    port = krb5_getportbyname(NULL, "kx", "tcp", htons(KX_PORT)); | ||||
| 	ret = doit_v5 (host, port, user, | ||||
| 		       passive_flag, debug_flag, keepalive_flag, tcp_flag); | ||||
|     } | ||||
| #endif | ||||
| #ifdef KRB4 | ||||
|     if (ret && use_v4) { | ||||
| 	if (port == 0) | ||||
| 	    port = k_getportbyname("kx", "tcp", htons(KX_PORT)); | ||||
| 	ret = doit_v4 (host, port, user,  | ||||
| 		       passive_flag, debug_flag, keepalive_flag, tcp_flag); | ||||
|     } | ||||
| #endif | ||||
|     return ret; | ||||
| } | ||||
|   | ||||
							
								
								
									
										373
									
								
								appl/kx/kxd.c
									
									
									
									
									
								
							
							
						
						
									
										373
									
								
								appl/kx/kxd.c
									
									
									
									
									
								
							| @@ -57,20 +57,8 @@ childhandler (int sig) | ||||
|      SIGRETURN(0); | ||||
| } | ||||
|  | ||||
| static void | ||||
| fatal(int, des_cblock *, des_key_schedule, | ||||
|       struct sockaddr_in *, struct sockaddr_in *, | ||||
|       char *format, ...) | ||||
| #ifdef __GNUC__ | ||||
| __attribute__ ((format (printf, 6, 7))) | ||||
| #endif | ||||
| ; | ||||
|  | ||||
| static void | ||||
| fatal (int fd, des_cblock *key, des_key_schedule schedule, | ||||
|        struct sockaddr_in *thisaddr, | ||||
|        struct sockaddr_in *thataddr, | ||||
|        char *format, ...) | ||||
| void | ||||
| fatal (kx_context *kc, int fd, char *format, ...) | ||||
| { | ||||
|     u_char msg[1024]; | ||||
|     u_char *p; | ||||
| @@ -83,9 +71,9 @@ fatal (int fd, des_cblock *key, des_key_schedule schedule, | ||||
|     vsnprintf (p + 4, sizeof(msg) - 5, format, args); | ||||
|     syslog (LOG_ERR, p + 4); | ||||
|     len = strlen (p + 4); | ||||
|     p += krb_put_int (len, p, 4, 4); | ||||
|     p += KRB_PUT_INT (len, p, 4, 4); | ||||
|     p += len; | ||||
|     write_encrypted (fd, msg, p - msg, schedule, key, thisaddr, thataddr); | ||||
|     kx_write (kc, fd, msg, p - msg); | ||||
|     va_end(args); | ||||
|     exit (1); | ||||
| } | ||||
| @@ -105,80 +93,68 @@ cleanup(int nsockets, struct x_socket *sockets) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int | ||||
| recv_conn (int sock, des_cblock *key, des_key_schedule schedule, | ||||
| 	   struct sockaddr_in *thisaddr, | ||||
| 	   struct sockaddr_in *thataddr, | ||||
| 	   int *dispnr, | ||||
| 	   int *nsockets, | ||||
| 	   struct x_socket **sockets, | ||||
| 	   int tcpp) | ||||
| { | ||||
|      int status; | ||||
|      KTEXT_ST ticket; | ||||
|      AUTH_DAT auth; | ||||
|      char user[ANAME_SZ]; | ||||
|      char instance[INST_SZ]; | ||||
|      int addrlen; | ||||
|      char version[KRB_SENDAUTH_VLEN + 1]; | ||||
|      struct passwd *passwd; | ||||
|      char remotehost[MaxHostNameLen]; | ||||
|      void *ret; | ||||
|      int len; | ||||
|      u_char msg[1024], *p; | ||||
|      u_int32_t tmp32; | ||||
|      int tmp; | ||||
|      int flags; | ||||
| /* | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|      addrlen = sizeof(*thisaddr); | ||||
|      if (getsockname (sock, (struct sockaddr *)thisaddr, &addrlen) < 0 || | ||||
| 	 addrlen != sizeof(*thisaddr)) { | ||||
| static int | ||||
| recv_conn (int sock, kx_context *kc, | ||||
| 	   int *dispnr, int *nsockets, struct x_socket **sockets, | ||||
| 	   int tcp_flag) | ||||
| { | ||||
|      u_char msg[1024], *p; | ||||
|      char user[256]; | ||||
|      int addrlen; | ||||
|      struct passwd *passwd; | ||||
|      struct sockaddr_in thisaddr, thataddr; | ||||
|      char remotehost[MaxHostNameLen]; | ||||
|      int ret = 1; | ||||
|      int flags; | ||||
|      int len; | ||||
|      u_int32_t tmp32; | ||||
|  | ||||
|      addrlen = sizeof(thisaddr); | ||||
|      if (getsockname (sock, (struct sockaddr *)&thisaddr, &addrlen) < 0 || | ||||
| 	 addrlen != sizeof(thisaddr)) { | ||||
| 	 syslog (LOG_ERR, "getsockname: %m"); | ||||
| 	 exit (1); | ||||
|      } | ||||
|      addrlen = sizeof(*thataddr); | ||||
|      if (getpeername (sock, (struct sockaddr *)thataddr, &addrlen) < 0 || | ||||
| 	 addrlen != sizeof(*thataddr)) { | ||||
|      addrlen = sizeof(thataddr); | ||||
|      if (getpeername (sock, (struct sockaddr *)&thataddr, &addrlen) < 0 || | ||||
| 	 addrlen != sizeof(thataddr)) { | ||||
| 	 syslog (LOG_ERR, "getpeername: %m"); | ||||
| 	 exit (1); | ||||
|      } | ||||
|  | ||||
|      inaddr2str (thataddr->sin_addr, remotehost, sizeof(remotehost)); | ||||
|      kc->thisaddr = thisaddr; | ||||
|      kc->thataddr = thataddr; | ||||
|  | ||||
|      k_getsockinst (sock, instance, sizeof(instance)); | ||||
|      status = krb_recvauth (KOPT_DO_MUTUAL, sock, &ticket, "rcmd", instance, | ||||
| 			    thataddr, thisaddr, &auth, "", schedule, | ||||
| 			    version); | ||||
|      if (status != KSUCCESS) { | ||||
| 	 syslog (LOG_ERR, "krb_recvauth: %s", | ||||
| 		 krb_get_err_text(status)); | ||||
| 	 exit(1); | ||||
|      inaddr2str (thataddr.sin_addr, remotehost, sizeof(remotehost)); | ||||
|  | ||||
|      if (net_read (sock, msg, 4) != 4) { | ||||
| 	 syslog (LOG_ERR, "read: %m"); | ||||
| 	 exit (1); | ||||
|      } | ||||
|      if( strncmp(version, KX_VERSION, KRB_SENDAUTH_VLEN) != 0) { | ||||
| 	 /* Try to be nice to old kx's */ | ||||
| 	 if (strncmp (version, KX_OLD_VERSION, KRB_SENDAUTH_VLEN) == 0) { | ||||
| 	     char *old_errmsg = "\001Old version of kx. Please upgrade."; | ||||
|  | ||||
| 	     syslog (LOG_ERR, "Old version client (%s)", version); | ||||
|  | ||||
| 	     krb_net_read (sock, user, sizeof(user)); | ||||
| 	     krb_net_write (sock, old_errmsg, strlen(old_errmsg) + 1); | ||||
| 	     exit (1); | ||||
| 	 } | ||||
|  | ||||
| 	 fatal(sock, key, schedule, thisaddr, thataddr, | ||||
| 	       "Bad version %s", version); | ||||
| #ifdef KRB5 | ||||
|      if (ret && recv_v5_auth (kc, sock, msg) == 0) | ||||
| 	 ret = 0; | ||||
| #endif | ||||
| #ifdef KRB4 | ||||
|      if (ret && recv_v4_auth (kc, sock, msg) == 0) | ||||
| 	 ret = 0; | ||||
| #endif | ||||
|      if (ret) { | ||||
| 	 syslog (LOG_ERR, "unrecognized auth protocol: %x %x %x %x"); | ||||
| 	 return 1; | ||||
|      } | ||||
|      memcpy(key, &auth.session, sizeof(des_cblock)); | ||||
|  | ||||
|      len = read_encrypted (sock, msg, sizeof(msg), &ret, | ||||
| 			   schedule, key, thataddr, thisaddr); | ||||
|      len = kx_read (kc, sock, msg, sizeof(msg)); | ||||
|      if (len < 0) | ||||
| 	 return 1; | ||||
|      p = (u_char *)ret; | ||||
|      p = (u_char *)msg; | ||||
|      if (*p != INIT) | ||||
| 	 fatal(sock, key, schedule, thisaddr, thataddr, | ||||
| 	       "Bad message"); | ||||
| 	 fatal(kc, sock, "Bad message"); | ||||
|      p++; | ||||
|      p += krb_get_int (p, &tmp32, 4, 0); | ||||
|      len = min(sizeof(user), tmp32); | ||||
| @@ -188,25 +164,21 @@ recv_conn (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|  | ||||
|      passwd = k_getpwnam (user); | ||||
|      if (passwd == NULL) | ||||
| 	  fatal (sock, key, schedule, thisaddr, thataddr, | ||||
| 		 "Cannot find uid"); | ||||
|      if (kuserok(&auth, user) != 0) | ||||
| 	  fatal (sock, key, schedule, thisaddr, thataddr, | ||||
| 		 "%s is not allowed to login as %s", | ||||
| 		 krb_unparse_name_long (auth.pname, | ||||
| 					auth.pinst, | ||||
| 					auth.prealm), | ||||
| 		 user); | ||||
| 	 fatal (kc, sock, "cannot find uid for %s", user); | ||||
|  | ||||
|      if (context_userok (kc, user) != 0) | ||||
| 	 fatal (kc, sock, "%s not allowed to login as %s", | ||||
| 		kc->user, user); | ||||
|  | ||||
|      flags = *p++; | ||||
|  | ||||
|      if (flags & PASSIVE) { | ||||
| 	 pid_t pid; | ||||
| 	 int tmp; | ||||
|  | ||||
| 	 tmp = get_xsockets (nsockets, sockets, tcpp); | ||||
| 	 tmp = get_xsockets (nsockets, sockets, tcp_flag); | ||||
| 	 if (tmp < 0) { | ||||
| 	     fatal (sock, key, schedule, thisaddr, thataddr, | ||||
| 		    "Cannot create X socket(s): %s", | ||||
| 	     fatal (kc, sock, "Cannot create X socket(s): %s", | ||||
| 		    strerror(errno)); | ||||
| 	 } | ||||
| 	 *dispnr = tmp; | ||||
| @@ -214,16 +186,14 @@ recv_conn (int sock, des_cblock *key, des_key_schedule schedule, | ||||
| 	 if (chown_xsockets (*nsockets, *sockets, | ||||
| 			    passwd->pw_uid, passwd->pw_gid)) { | ||||
| 	     cleanup (*nsockets, *sockets); | ||||
| 	     fatal (sock, key, schedule, thisaddr, thataddr, | ||||
| 		    "Cannot chown sockets: %s", | ||||
| 	     fatal (kc, sock, "Cannot chown sockets: %s", | ||||
| 		    strerror(errno)); | ||||
| 	 } | ||||
|  | ||||
| 	 pid = fork(); | ||||
| 	 if (pid == -1) { | ||||
| 	     cleanup (*nsockets, *sockets); | ||||
| 	     fatal (sock, key, schedule, thisaddr, thataddr, | ||||
| 		    "fork: %s", strerror(errno)); | ||||
| 	     fatal (kc, sock, "fork: %s", strerror(errno)); | ||||
| 	 } else if (pid != 0) { | ||||
| 	     int status; | ||||
|  | ||||
| @@ -239,14 +209,12 @@ recv_conn (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|      if (setgid (passwd->pw_gid) || | ||||
| 	 initgroups(passwd->pw_name, passwd->pw_gid) || | ||||
| 	 setuid(passwd->pw_uid)) { | ||||
| 	 fatal (sock, key, schedule, thisaddr, thataddr, | ||||
| 		"Cannot set uid"); | ||||
| 	 fatal (kc, sock, "cannot set uid"); | ||||
|      } | ||||
|      syslog (LOG_INFO, "from %s(%s): %s -> %s", | ||||
| 	     remotehost, | ||||
| 	     inet_ntoa(thataddr->sin_addr), | ||||
| 	     krb_unparse_name_long (auth.pname, auth.pinst, auth.prealm), | ||||
| 	     user); | ||||
| 	     inet_ntoa(thataddr.sin_addr), | ||||
| 	     kc->user); | ||||
|      umask(077); | ||||
|      if (!(flags & PASSIVE)) { | ||||
| 	 p += krb_get_int (p, &tmp32, 4, 0); | ||||
| @@ -276,35 +244,32 @@ recv_conn (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|  */ | ||||
|  | ||||
| static int | ||||
| passive_session (int fd, int sock, int cookiesp, des_cblock *key, | ||||
| 		 des_key_schedule schedule) | ||||
| passive_session (kx_context *kc, int fd, int sock, int cookiesp) | ||||
| { | ||||
|     if (verify_and_remove_cookies (fd, sock, cookiesp)) | ||||
| 	return 1; | ||||
|     else | ||||
| 	return copy_encrypted (fd, sock, key, schedule); | ||||
| 	return copy_encrypted (kc, fd, sock); | ||||
| } | ||||
|  | ||||
| static int | ||||
| active_session (int fd, int sock, int cookiesp, des_cblock *key, | ||||
| 		des_key_schedule schedule) | ||||
| active_session (kx_context *kc, int fd, int sock, int cookiesp) | ||||
| { | ||||
|     fd = connect_local_xsocket(0); | ||||
|  | ||||
|     if (replace_cookie (fd, sock, xauthfile, cookiesp)) | ||||
| 	return 1; | ||||
|     else | ||||
| 	return copy_encrypted (fd, sock, key, schedule); | ||||
| 	return copy_encrypted (kc, fd, sock); | ||||
| } | ||||
|  | ||||
| static int | ||||
| doit_conn (int fd, int meta_sock, int flags, int cookiesp, | ||||
| 	   des_cblock *key, des_key_schedule schedule, | ||||
| 	   struct sockaddr_in *thisaddr, | ||||
| 	   struct sockaddr_in *thataddr) | ||||
| doit_conn (kx_context *kc, | ||||
| 	   int fd, int meta_sock, int flags, int cookiesp) | ||||
| { | ||||
|     int sock, sock2; | ||||
|     struct sockaddr_in addr; | ||||
|     struct sockaddr_in thisaddr; | ||||
|     int addrlen; | ||||
|     u_char msg[1024], *p; | ||||
|  | ||||
| @@ -334,8 +299,7 @@ doit_conn (int fd, int meta_sock, int flags, int cookiesp, | ||||
| 	return 1; | ||||
|     } | ||||
|     addrlen = sizeof(addr); | ||||
|     if (getsockname (sock, (struct sockaddr *)&addr, | ||||
| 		     &addrlen) < 0) { | ||||
|     if (getsockname (sock, (struct sockaddr *)&addr, &addrlen) < 0) { | ||||
| 	syslog (LOG_ERR, "getsockname: %m"); | ||||
| 	return 1; | ||||
|     } | ||||
| @@ -345,15 +309,15 @@ doit_conn (int fd, int meta_sock, int flags, int cookiesp, | ||||
|     } | ||||
|     p = msg; | ||||
|     *p++ = NEW_CONN; | ||||
|     p += krb_put_int (ntohs(addr.sin_port), p, 4, 4); | ||||
|     p += KRB_PUT_INT (ntohs(addr.sin_port), p, 4, 4); | ||||
|  | ||||
|     if (write_encrypted (meta_sock, msg, p - msg, schedule, key, | ||||
| 			 thisaddr, thataddr) < 0) { | ||||
|     if (kx_write (kc, meta_sock, msg, p - msg) < 0) { | ||||
| 	syslog (LOG_ERR, "write: %m"); | ||||
| 	return 1; | ||||
|     } | ||||
|  | ||||
|     sock2 = accept (sock, (struct sockaddr *)thisaddr, &addrlen); | ||||
|     addrlen = sizeof(thisaddr); | ||||
|     sock2 = accept (sock, (struct sockaddr *)&thisaddr, &addrlen); | ||||
|     if (sock2 < 0) { | ||||
| 	syslog (LOG_ERR, "accept: %m"); | ||||
| 	return 1; | ||||
| @@ -362,9 +326,9 @@ doit_conn (int fd, int meta_sock, int flags, int cookiesp, | ||||
|     close (meta_sock); | ||||
|  | ||||
|     if (flags & PASSIVE) | ||||
| 	return passive_session (fd, sock2, cookiesp, key, schedule); | ||||
| 	return passive_session (kc, fd, sock2, cookiesp); | ||||
|     else | ||||
| 	return active_session (fd, sock2, cookiesp, key, schedule); | ||||
| 	return active_session (kc, fd, sock2, cookiesp); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -372,18 +336,14 @@ doit_conn (int fd, int meta_sock, int flags, int cookiesp, | ||||
|  */ | ||||
|  | ||||
| static void | ||||
| check_user_console (int fd, des_cblock *key, des_key_schedule schedule, | ||||
| 		    struct sockaddr_in *thisaddr, | ||||
| 		    struct sockaddr_in *thataddr) | ||||
| check_user_console (kx_context *kc, int fd) | ||||
| { | ||||
|      struct stat sb; | ||||
|  | ||||
|      if (stat ("/dev/console", &sb) < 0) | ||||
| 	 fatal (fd, key, schedule, thisaddr, thataddr, | ||||
| 		"Cannot stat /dev/console"); | ||||
| 	 fatal (kc, fd, "Cannot stat /dev/console: %s", strerror(errno)); | ||||
|      if (getuid() != sb.st_uid) | ||||
| 	 fatal (fd, key, schedule, thisaddr, thataddr, | ||||
| 		"Permission denied"); | ||||
| 	 fatal (kc, fd, "Permission denied"); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -391,10 +351,13 @@ check_user_console (int fd, des_cblock *key, des_key_schedule schedule, | ||||
|  */ | ||||
|  | ||||
| static int | ||||
| doit_passive (int sock, des_cblock *key, des_key_schedule schedule, | ||||
| 	      struct sockaddr_in *me, struct sockaddr_in *him, int flags, | ||||
| 	      int displaynr, int nsockets, struct x_socket *sockets, | ||||
| 	      int tcpp) | ||||
| doit_passive (kx_context *kc, | ||||
| 	      int sock, | ||||
| 	      int flags, | ||||
| 	      int dispnr, | ||||
| 	      int nsockets, | ||||
| 	      struct x_socket *sockets, | ||||
| 	      int tcp_flag) | ||||
| { | ||||
|     int tmp; | ||||
|     int len; | ||||
| @@ -402,8 +365,8 @@ doit_passive (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|     u_char msg[1024], *p; | ||||
|     int error; | ||||
|  | ||||
|     display_num = displaynr; | ||||
|     if (tcpp) | ||||
|     display_num = dispnr; | ||||
|     if (tcp_flag) | ||||
| 	snprintf (display, display_size, "localhost:%u", display_num); | ||||
|     else | ||||
| 	snprintf (display, display_size, ":%u", display_num); | ||||
| @@ -411,9 +374,7 @@ doit_passive (int sock, des_cblock *key, des_key_schedule schedule, | ||||
| 				     cookie, cookie_len); | ||||
|     if (error) { | ||||
| 	cleanup(nsockets, sockets); | ||||
| 	fatal (sock, key, schedule, me, him, | ||||
| 	       "Cookie-creation failed with: %s", | ||||
| 	       strerror(error)); | ||||
| 	fatal (kc, sock, "Cookie-creation failed: %s", strerror(error)); | ||||
| 	return 1; | ||||
|     } | ||||
|  | ||||
| @@ -423,7 +384,7 @@ doit_passive (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|     --rem; | ||||
|  | ||||
|     len = strlen (display); | ||||
|     tmp = krb_put_int (len, p, rem, 4); | ||||
|     tmp = KRB_PUT_INT (len, p, rem, 4); | ||||
|     if (tmp < 0 || rem < len + 4) { | ||||
| 	syslog (LOG_ERR, "doit: buffer too small"); | ||||
| 	cleanup(nsockets, sockets); | ||||
| @@ -437,7 +398,7 @@ doit_passive (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|     rem -= len; | ||||
|  | ||||
|     len = strlen (xauthfile); | ||||
|     tmp = krb_put_int (len, p, rem, 4); | ||||
|     tmp = KRB_PUT_INT (len, p, rem, 4); | ||||
|     if (tmp < 0 || rem < len + 4) { | ||||
| 	syslog (LOG_ERR, "doit: buffer too small"); | ||||
| 	cleanup(nsockets, sockets); | ||||
| @@ -450,8 +411,7 @@ doit_passive (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|     p += len; | ||||
|     rem -= len; | ||||
| 	   | ||||
|     if(write_encrypted (sock, msg, p - msg, schedule, key, | ||||
| 			me, him) < 0) { | ||||
|     if(kx_write (kc, sock, msg, p - msg) < 0) { | ||||
| 	syslog (LOG_ERR, "write: %m"); | ||||
| 	cleanup(nsockets, sockets); | ||||
| 	return 1; | ||||
| @@ -550,8 +510,7 @@ doit_passive (int sock, des_cblock *key, des_key_schedule schedule, | ||||
| 	} else if (child == 0) { | ||||
| 	    for (i = 0; i < nsockets; ++i) | ||||
| 		close (sockets[i].fd); | ||||
| 	    return doit_conn (fd, sock, flags, cookiesp, | ||||
| 			      key, schedule, me, him); | ||||
| 	    return doit_conn (kc, fd, sock, flags, cookiesp); | ||||
| 	} else { | ||||
| 	    close (fd); | ||||
| 	} | ||||
| @@ -563,35 +522,32 @@ doit_passive (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|  */ | ||||
|  | ||||
| static int | ||||
| doit_active (int sock, des_cblock *key, des_key_schedule schedule, | ||||
| 	     struct sockaddr_in *me, struct sockaddr_in *him, | ||||
| 	     int flags, int tcpp) | ||||
| doit_active (kx_context *kc, | ||||
| 	     int sock, | ||||
| 	     int flags, | ||||
| 	     int tcp_flag) | ||||
| { | ||||
|     u_char msg[1024], *p; | ||||
|  | ||||
|     check_user_console (sock, key, schedule, me, him); | ||||
|     check_user_console (kc, sock); | ||||
|  | ||||
|     p = msg; | ||||
|     *p++ = ACK; | ||||
| 	   | ||||
|     if(write_encrypted (sock, msg, p - msg, schedule, key, | ||||
| 			me, him) < 0) { | ||||
|     if(kx_write (kc, sock, msg, p - msg) < 0) { | ||||
| 	syslog (LOG_ERR, "write: %m"); | ||||
| 	return 1; | ||||
|     } | ||||
|     for (;;) { | ||||
| 	pid_t child; | ||||
| 	int len; | ||||
| 	void *ret; | ||||
| 	       | ||||
| 	len = read_encrypted (sock, msg, sizeof(msg), &ret, | ||||
| 			      schedule, key, | ||||
| 			      him, me); | ||||
| 	len = kx_read (kc, sock, msg, sizeof(msg)); | ||||
| 	if (len < 0) { | ||||
| 	    syslog (LOG_ERR, "read: %m"); | ||||
| 	    return 1; | ||||
| 	} | ||||
| 	p = (u_char *)ret; | ||||
| 	p = (u_char *)msg; | ||||
| 	if (*p != NEW_CONN) { | ||||
| 	    syslog (LOG_ERR, "bad_message: %d", *p); | ||||
| 	    return 1; | ||||
| @@ -602,8 +558,7 @@ doit_active (int sock, des_cblock *key, des_key_schedule schedule, | ||||
| 	    syslog (LOG_ERR, "fork: %m"); | ||||
| 	    return 1; | ||||
| 	} else if (child == 0) { | ||||
| 	    return doit_conn (sock, sock, flags, 1, | ||||
| 			      key, schedule, me, him); | ||||
| 	    return doit_conn (kc, sock, sock, flags, 1); | ||||
| 	} else { | ||||
| 	} | ||||
|     } | ||||
| @@ -614,31 +569,49 @@ doit_active (int sock, des_cblock *key, des_key_schedule schedule, | ||||
|  */ | ||||
|  | ||||
| static int | ||||
| doit(int sock, int tcpp) | ||||
| doit(int sock, int tcp_flag) | ||||
| { | ||||
|      des_key_schedule schedule; | ||||
|      des_cblock key; | ||||
|      struct sockaddr_in me, him; | ||||
|      int flags; | ||||
|      struct x_socket *sockets; | ||||
|      int nsockets; | ||||
|      int dispnr; | ||||
|     int ret; | ||||
|     kx_context context; | ||||
|     int dispnr; | ||||
|     int nsockets; | ||||
|     struct x_socket *sockets; | ||||
|     int flags; | ||||
|  | ||||
|      flags = recv_conn (sock, &key, schedule, &me, &him, | ||||
| 			&dispnr, &nsockets, &sockets, tcpp); | ||||
|     flags = recv_conn (sock, &context, &dispnr, &nsockets, &sockets, tcp_flag); | ||||
|  | ||||
|      if (flags & PASSIVE) | ||||
| 	 return doit_passive (sock, &key, schedule, &me, &him, flags, | ||||
| 			      dispnr, nsockets, sockets, tcpp); | ||||
|      else | ||||
| 	 return doit_active (sock, &key, schedule, &me, &him, flags, tcpp); | ||||
|     if (flags & PASSIVE) | ||||
| 	ret = doit_passive (&context, sock, flags, dispnr, | ||||
| 			    nsockets, sockets, tcp_flag); | ||||
|     else | ||||
| 	ret = doit_active (&context, sock, flags, tcp_flag); | ||||
|     context_destroy (&context); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static char *port_str		= NULL; | ||||
| static int inetd_flag		= 0; | ||||
| static int tcp_flag		= 0; | ||||
| static int version_flag		= 0; | ||||
| static int help_flag		= 0; | ||||
|  | ||||
| struct getargs args[] = { | ||||
|     { "inetd",		'i',	arg_negative_flag,	&inetd_flag, | ||||
|       "Not started from inetd" }, | ||||
|     { "port",		'p',	arg_string,	&port_str,	"Use this port", | ||||
|       "port" }, | ||||
|     { "version",	0, 	arg_flag,		&version_flag }, | ||||
|     { "help",		0, 	arg_flag,		&help_flag } | ||||
| }; | ||||
|  | ||||
| static void | ||||
| usage (void) | ||||
| usage(int ret) | ||||
| { | ||||
|      fprintf (stderr, "Usage: %s [-i] [-t] [-p port]\n", __progname); | ||||
|      exit (1); | ||||
|     arg_printusage (args, | ||||
| 		    sizeof(args) / sizeof(args[0]), | ||||
| 		    NULL, | ||||
| 		    "host"); | ||||
|     exit (ret); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -648,34 +621,50 @@ usage (void) | ||||
| int | ||||
| main (int argc, char **argv) | ||||
| { | ||||
|      int c; | ||||
|      int no_inetd = 0; | ||||
|      int tcpp = 0; | ||||
|      int port = 0; | ||||
|     int port; | ||||
|     int optind = 0; | ||||
|  | ||||
|      set_progname (argv[0]); | ||||
|     set_progname (argv[0]); | ||||
|     roken_openlog ("kxd", LOG_ODELAY | LOG_PID, LOG_DAEMON); | ||||
|  | ||||
|      while( (c = getopt (argc, argv, "itp:")) != EOF) { | ||||
| 	  switch (c) { | ||||
| 	  case 'i': | ||||
| 	       no_inetd = 1; | ||||
| 	       break; | ||||
| 	  case 't': | ||||
| 	       tcpp = 1; | ||||
| 	       break; | ||||
| 	  case 'p': | ||||
| 	      port = htons(atoi (optarg)); | ||||
| 	      break; | ||||
| 	  case '?': | ||||
| 	  default: | ||||
| 	       usage (); | ||||
| 	  } | ||||
|      } | ||||
|     if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv, | ||||
| 		&optind)) | ||||
| 	usage (1); | ||||
|  | ||||
|     if (help_flag) | ||||
| 	usage (0); | ||||
|  | ||||
|     if (version_flag) { | ||||
| 	print_version (NULL); | ||||
| 	return 0; | ||||
|     } | ||||
|  | ||||
|     if(port_str) { | ||||
| 	struct servent *s = roken_getservbyname (port_str, "tcp"); | ||||
|  | ||||
| 	if (s) | ||||
| 	    port = s->s_port; | ||||
| 	else { | ||||
| 	    char *ptr; | ||||
|  | ||||
| 	    port = strtol (port_str, &ptr, 10); | ||||
| 	    if (port == 0 && ptr == port_str) | ||||
| 		errx (1, "bad port `%s'", port_str); | ||||
| 	    port = htons(port); | ||||
| 	} | ||||
|     } else { | ||||
| #if defined(KRB5) | ||||
| 	port = krb5_getportbyname(NULL, "kx", "tcp", htons(KX_PORT)); | ||||
| #elif defined(KRB4) | ||||
| 	port = k_getportbyname ("kx", "tcp", htons(KX_PORT)); | ||||
| #else | ||||
| #error define KRB4 or KRB5 | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     if (!inetd_flag) | ||||
| 	mini_inetd (port); | ||||
|  | ||||
|      if (no_inetd) | ||||
| 	  mini_inetd (port ? port : k_getportbyname("kx", "tcp", | ||||
| 						    htons(KX_PORT))); | ||||
|      roken_openlog(__progname, LOG_PID|LOG_CONS, LOG_DAEMON); | ||||
|      signal (SIGCHLD, childhandler); | ||||
|      return doit(STDIN_FILENO, tcpp); | ||||
|      return doit(STDIN_FILENO, tcp_flag); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Assar Westerlund
					Assar Westerlund