/[inetutils]/inetutils/libinetutils/kcmd.c
ViewVC logotype

Diff of /inetutils/libinetutils/kcmd.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by alainm, Thu Jul 6 04:21:07 2000 UTC revision 1.3 by gray, Tue Oct 11 11:17:54 2005 UTC
# Line 28  Line 28 
28   */   */
29    
30  #ifndef lint  #ifndef lint
31  static char Xsccsid[] = "derived from @(#)rcmd.c 5.17 (Berkeley) 6/27/88";  static char     Xsccsid[] = "derived from @(#)rcmd.c 5.17 (Berkeley) 6/27/88";
32  static char sccsid[] = "@(#)kcmd.c      8.2 (Berkeley) 8/19/93";  static char     sccsid[] = "@(#)kcmd.c  8.2 (Berkeley) 8/19/93";
33  #endif /* not lint */  #endif /* not lint */
34    
35  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
36  #include <config.h>  #include <config.h>
37  #endif  #endif
38    
39  #ifdef KERBEROS  #if defined(KERBEROS) || defined(SHISHI)
40    
41  #include <sys/param.h>  #include <sys/param.h>
42  #include <sys/file.h>  #include <sys/file.h>
# Line 46  static char sccsid[] = "@(#)kcmd.c     8.2 ( Line 46  static char sccsid[] = "@(#)kcmd.c     8.2 (
46  #include <netinet/in.h>  #include <netinet/in.h>
47  #include <arpa/inet.h>  #include <arpa/inet.h>
48    
49  #include <kerberosIV/des.h>  #if defined(KERBEROS)
50  #include <kerberosIV/krb.h>  # include <kerberosIV/des.h>
51  #include <kerberosIV/kparse.h>  # include <kerberosIV/krb.h>
52    #elif defined(SHISHI)
53    # include <shishi.h>
54    # include "shishi_def.h"
55    #endif
56    
57  #include <ctype.h>  #include <ctype.h>
58  #include <errno.h>  #include <errno.h>
# Line 64  static char sccsid[] = "@(#)kcmd.c     8.2 ( Line 68  static char sccsid[] = "@(#)kcmd.c     8.2 (
68  #define MAXHOSTNAMELEN 64  #define MAXHOSTNAMELEN 64
69  #endif  #endif
70    
71  #define START_PORT      5120     /* arbitrary */  #define START_PORT      5120    /* arbitrary */
72    
73  int     getport __P((int *));  int getport     __P ((int *));
74    
75    #if defined (KERBEROS)
76  int  int
77  kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm,  kcmd (int *sock, char **ahost, u_short rport, char *locuser,
78      cred, schedule, msg_data, laddr, faddr, authopts)        char *remuser, char *cmd, int *fd2p, KTEXT ticket,
79          int *sock;        char *service, char *realm,
80          char **ahost;        CREDENTIALS * cred, Key_schedule schedule, MSG_DAT * msg_data,
81          u_short rport;        struct sockaddr_in *laddr, struct sockaddr_in *faddr, long authopts)
82          char *locuser, *remuser, *cmd;  #elif defined(SHISHI)
83          int *fd2p;  int
84          KTEXT ticket;  kcmd (Shishi ** h, int *sock, char **ahost, u_short rport, char *locuser,
85          char *service;        char **remuser, char *cmd, int *fd2p, char *service, char *realm,
86          char *realm;        Shishi_key ** key,
87          CREDENTIALS *cred;        struct sockaddr_in *laddr, struct sockaddr_in *faddr, long authopts)
88          Key_schedule schedule;  #endif
         MSG_DAT *msg_data;  
         struct sockaddr_in *laddr, *faddr;  
         long authopts;  
89  {  {
90          int s, timo = 1, pid;    int             s, timo = 1, pid;
91          long oldmask;    long            oldmask;
92          struct sockaddr_in sin, from;    struct sockaddr_in sin, from;
93          char c;    char            c;
94    
95  #ifdef ATHENA_COMPAT  #ifdef ATHENA_COMPAT
96          int lport = IPPORT_RESERVED - 1;    int             lport = IPPORT_RESERVED - 1;
97  #else  #else
98          int lport = START_PORT;    int             lport = START_PORT;
99    #endif
100      struct hostent *hp;
101      int             rc;
102      char           *host_save;
103      int             status;
104    
105    #if defined(SHISHI)
106      int             zero = 0;
107  #endif  #endif
         struct hostent *hp;  
         int rc;  
         char *host_save;  
         int status;  
   
         pid = getpid();  
         hp = gethostbyname(*ahost);  
         if (hp == NULL) {  
                 /* fprintf(stderr, "%s: unknown host\n", *ahost); */  
                 return (-1);  
         }  
108    
109          host_save = malloc(strlen(hp->h_name) + 1);    pid = getpid ();
110          strcpy(host_save, hp->h_name);    hp = gethostbyname (*ahost);
111          *ahost = host_save;    if (hp == NULL)
112        {
113          /* fprintf(stderr, "%s: unknown host\n", *ahost); */
114          return (-1);
115        }
116    
117      host_save = malloc (strlen (hp->h_name) + 1);
118      strcpy (host_save, hp->h_name);
119      *ahost = host_save;
120    
121  #ifdef KERBEROS  #ifdef KERBEROS
122          /* If realm is null, look up from table */    /* If realm is null, look up from table */
123          if (realm == NULL || realm[0] == '\0')    if (realm == NULL || realm[0] == '\0')
124                  realm = krb_realmofhost(host_save);      realm = krb_realmofhost (host_save);
125  #endif /* KERBEROS */  #endif /* KERBEROS */
126    
127          oldmask = sigblock(sigmask(SIGURG));    oldmask = sigblock (sigmask (SIGURG));
128          for (;;) {    for (;;)
129                  s = getport(&lport);      {
130                  if (s < 0) {        s = getport (&lport);
131                          if (errno == EAGAIN)        if (s < 0)
132                                  fprintf(stderr,          {
133                                          "kcmd(socket): All ports in use\n");            if (errno == EAGAIN)
134                          else              fprintf (stderr, "kcmd(socket): All ports in use\n");
135                                  perror("kcmd: socket");            else
136                          sigsetmask(oldmask);              perror ("kcmd: socket");
137                          return (-1);            sigsetmask (oldmask);
138                  }            return (-1);
139                  fcntl(s, F_SETOWN, pid);          }
140                  sin.sin_family = hp->h_addrtype;        fcntl (s, F_SETOWN, pid);
141          sin.sin_family = hp->h_addrtype;
142  #if defined(ultrix) || defined(sun)  #if defined(ultrix) || defined(sun)
143                  bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);        bcopy (hp->h_addr, (caddr_t) & sin.sin_addr, hp->h_length);
144  #else  #else
145                  bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);        bcopy (hp->h_addr_list[0], (caddr_t) & sin.sin_addr, hp->h_length);
146  #endif  #endif
147                  sin.sin_port = rport;        sin.sin_port = rport;
                 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)  
                         break;  
                 (void) close(s);  
                 if (errno == EADDRINUSE) {  
                         lport--;  
                         continue;  
                 }  
                 /*  
                  * don't wait very long for Kerberos rcmd.  
                  */  
                 if (errno == ECONNREFUSED && timo <= 4) {  
                         /* sleep(timo); don't wait at all here */  
                         timo *= 2;  
                         continue;  
                 }  
 #if !(defined(ultrix) || defined(sun))  
                 if (hp->h_addr_list[1] != NULL) {  
                         int oerrno = errno;  
148    
149                          fprintf(stderr,        if (connect (s, (struct sockaddr *) &sin, sizeof (sin)) >= 0)
150                              "kcmd: connect to address %s: ",          break;
151                              inet_ntoa(sin.sin_addr));        close (s);
152                          errno = oerrno;        if (errno == EADDRINUSE)
153                          perror(NULL);          {
154                          hp->h_addr_list++;            lport--;
155                          bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,            continue;
156                              hp->h_length);          }
157                          fprintf(stderr, "Trying %s...\n",        /*
158                                  inet_ntoa(sin.sin_addr));         * don't wait very long for Kerberos rcmd.
159                          continue;         */
160                  }        if (errno == ECONNREFUSED && timo <= 4)
161            {
162              /* sleep(timo); don't wait at all here */
163              timo *= 2;
164              continue;
165            }
166    #if !(defined(ultrix) || defined(sun))
167          if (hp->h_addr_list[1] != NULL)
168            {
169              int             oerrno = errno;
170    
171              fprintf (stderr,
172                       "kcmd: connect to address %s: ", inet_ntoa (sin.sin_addr));
173              errno = oerrno;
174              perror (NULL);
175              hp->h_addr_list++;
176              bcopy (hp->h_addr_list[0], (caddr_t) & sin.sin_addr, hp->h_length);
177              fprintf (stderr, "Trying %s...\n", inet_ntoa (sin.sin_addr));
178              continue;
179            }
180  #endif /* !(defined(ultrix) || defined(sun)) */  #endif /* !(defined(ultrix) || defined(sun)) */
181                  if (errno != ECONNREFUSED)        if (errno != ECONNREFUSED)
182                          perror(hp->h_name);          perror (hp->h_name);
183                  sigsetmask(oldmask);        sigsetmask (oldmask);
184                  return (-1);  
185          }        return (-1);
186          lport--;      }
187          if (fd2p == 0) {    lport--;
188                  write(s, "", 1);    if (fd2p == 0)
189                  lport = 0;      {
190          } else {        write (s, "", 1);
191                  char num[8];        lport = 0;
192                  int s2 = getport(&lport), s3;      }
193                  int len = sizeof(from);    else
194        {
195                  if (s2 < 0) {        char            num[8];
196                          status = -1;        int             s2 = getport (&lport), s3;
197                          goto bad;        int             len = sizeof (from);
198                  }  
199                  listen(s2, 1);        if (s2 < 0)
200                  (void) sprintf(num, "%d", lport);          {
201                  if (write(s, num, strlen(num) + 1) != strlen(num) + 1) {            status = -1;
202                          perror("kcmd(write): setting up stderr");            goto bad;
203                          (void) close(s2);          }
204                          status = -1;        listen (s2, 1);
205                          goto bad;        sprintf (num, "%d", lport);
206                  }        if (write (s, num, strlen (num) + 1) != strlen (num) + 1)
207                  s3 = accept(s2, (struct sockaddr *)&from, &len);          {
208                  (void) close(s2);            perror ("kcmd(write): setting up stderr");
209                  if (s3 < 0) {            close (s2);
210                          perror("kcmd:accept");            status = -1;
211                          lport = 0;            goto bad;
                         status = -1;  
                         goto bad;  
                 }  
                 *fd2p = s3;  
                 from.sin_port = ntohs((u_short)from.sin_port);  
                 if (from.sin_family != AF_INET ||  
                     from.sin_port >= IPPORT_RESERVED) {  
                         fprintf(stderr,  
                          "kcmd(socket): protocol failure in circuit setup.\n");  
                         status = -1;  
                         goto bad2;  
                 }  
         }  
         /*  
          * Kerberos-authenticated service.  Don't have to send locuser,  
          * since its already in the ticket, and we'll extract it on  
          * the other side.  
          */  
         /* (void) write(s, locuser, strlen(locuser)+1); */  
   
         /* set up the needed stuff for mutual auth, but only if necessary */  
         if (authopts & KOPT_DO_MUTUAL) {  
                 int sin_len;  
                 *faddr = sin;  
   
                 sin_len = sizeof(struct sockaddr_in);  
                 if (getsockname(s, (struct sockaddr *)laddr, &sin_len) < 0) {  
                         perror("kcmd(getsockname)");  
                         status = -1;  
                         goto bad2;  
                 }  
212          }          }
213          s3 = accept (s2, (struct sockaddr *) &from, &len);
214          close (s2);
215          if (s3 < 0)
216            {
217              perror ("kcmd:accept");
218              lport = 0;
219              status = -1;
220              goto bad;
221            }
222          *fd2p = s3;
223          from.sin_port = ntohs ((u_short) from.sin_port);
224          if (from.sin_family != AF_INET || from.sin_port >= IPPORT_RESERVED)
225            {
226              fprintf (stderr,
227                       "kcmd(socket): protocol failure in circuit setup.\n");
228              status = -1;
229              goto bad2;
230            }
231        }
232      /*
233       * Kerberos-authenticated service.  Don't have to send locuser,
234       * since its already in the ticket, and we'll extract it on
235       * the other side.
236       */
237      /* write(s, locuser, strlen(locuser)+1); */
238    
239      /* set up the needed stuff for mutual auth, but only if necessary */
240  #ifdef KERBEROS  #ifdef KERBEROS
241          if ((status = krb_sendauth(authopts, s, ticket, service, *ahost,    if (authopts & KOPT_DO_MUTUAL)
242                                 realm, (unsigned long) getpid(), msg_data,      {
243                                 cred, schedule,        int             sin_len;
244                                 laddr,  
245                                 faddr,        *faddr = sin;
246                                 "KCMDV0.1")) != KSUCCESS)  
247                  goto bad2;        sin_len = sizeof (struct sockaddr_in);
248  #endif /* KERBEROS */        if (getsockname (s, (struct sockaddr *) laddr, &sin_len) < 0)
249            {
250              perror ("kcmd(getsockname)");
251              status = -1;
252              goto bad2;
253            }
254        }
255    
256      if ((status = krb_sendauth (authopts, s, ticket, service, *ahost,
257                                  realm, (unsigned long) getpid (), msg_data,
258                                  cred, schedule,
259                                  laddr, faddr, "KCMDV0.1")) != KSUCCESS)
260        goto bad2;
261    #elif defined(SHISHI)
262      if (authopts & SHISHI_APOPTIONS_MUTUAL_REQUIRED)
263        {
264          int             sin_len;
265    
266          *faddr = sin;
267    
268          sin_len = sizeof (struct sockaddr_in);
269          if (getsockname (s, (struct sockaddr *) laddr, &sin_len) < 0)
270            {
271              perror ("kcmd(getsockname)");
272              status = -1;
273              goto bad2;
274            }
275        }
276    
277          (void) write(s, remuser, strlen(remuser)+1);    if ((status =
278          (void) write(s, cmd, strlen(cmd)+1);         shishi_auth (h, 0, remuser, *ahost, s, cmd, rport, key,
279                        realm)) != SHISHI_OK)
280        goto bad2;
281    
282          if ((rc = read(s, &c, 1)) != 1) {  #endif /* SHISHI */
283                  if (rc == -1)  
284                          perror(*ahost);    write (s, *remuser, strlen (*remuser) + 1);
285                  else    write (s, cmd, strlen (cmd) + 1);
286                          fprintf(stderr,"kcmd: bad connection with remote host\n");  
287                  status = -1;  #ifdef SHISHI
288                  goto bad2;    write (s, *remuser, strlen (*remuser) + 1);
289          }    write (s, &zero, sizeof (int));
290          if (c != '\0') {  #endif
291                  while (read(s, &c, 1) == 1) {  
292                          (void) write(2, &c, 1);    if ((rc = read (s, &c, 1)) != 1)
293                          if (c == '\n')      {
294                                  break;        if (rc == -1)
295                  }          perror (*ahost);
296                  status = -1;        else
297                  goto bad2;          fprintf (stderr, "kcmd: bad connection with remote host\n");
298          }        status = -1;
299          sigsetmask(oldmask);        goto bad2;
300          *sock = s;      }
301          return (KSUCCESS);    if (c != '\0')
302        {
303          while (read (s, &c, 1) == 1)
304            {
305              write (2, &c, 1);
306              if (c == '\n')
307                break;
308            }
309          status = -1;
310          goto bad2;
311        }
312      sigsetmask (oldmask);
313      *sock = s;
314    #if defined(KERBEROS)
315      return (KSUCCESS);
316    #elif defined(SHISHI)
317      return (SHISHI_OK);
318    #endif
319  bad2:  bad2:
320          if (lport)    if (lport)
321                  (void) close(*fd2p);      close (*fd2p);
322  bad:  bad:
323          (void) close(s);    close (s);
324          sigsetmask(oldmask);    sigsetmask (oldmask);
325          return (status);    return (status);
326  }  }
327    
328  int  int
329  getport(alport)  getport (int *alport)
         int *alport;  
330  {  {
331          struct sockaddr_in sin;    struct sockaddr_in sin;
332          int s;    int             s;
333    
334          sin.sin_family = AF_INET;    sin.sin_family = AF_INET;
335          sin.sin_addr.s_addr = INADDR_ANY;    sin.sin_addr.s_addr = INADDR_ANY;
336          s = socket(AF_INET, SOCK_STREAM, 0);    s = socket (AF_INET, SOCK_STREAM, 0);
337          if (s < 0)    if (s < 0)
338                  return (-1);      return (-1);
339          for (;;) {    for (;;)
340                  sin.sin_port = htons((u_short)*alport);      {
341                  if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)        sin.sin_port = htons ((u_short) * alport);
342                          return (s);        if (bind (s, (struct sockaddr *) &sin, sizeof (sin)) >= 0)
343                  if (errno != EADDRINUSE) {          return (s);
344                          (void) close(s);        if (errno != EADDRINUSE)
345                          return (-1);          {
346                  }            close (s);
347                  (*alport)--;            return (-1);
348            }
349          (*alport)--;
350  #ifdef ATHENA_COMPAT  #ifdef ATHENA_COMPAT
351                  if (*alport == IPPORT_RESERVED/2) {        if (*alport == IPPORT_RESERVED / 2)
352            {
353  #else  #else
354                  if (*alport == IPPORT_RESERVED) {        if (*alport == IPPORT_RESERVED)
355            {
356  #endif  #endif
357                          (void) close(s);            close (s);
358                          errno = EAGAIN;         /* close */            errno = EAGAIN;       /* close */
359                          return (-1);            return (-1);
                 }  
360          }          }
361        }
362  }  }
363    
364  #endif /* KERBEROS */  #endif /* KERBEROS */

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26