]> asedeno.scripts.mit.edu Git - 1ts-debian.git/commitdiff
ostensibly accept both sorts of authentication when offering brain dumps, and have...
authorkcr <kcr@cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f>
Fri, 28 Dec 2007 03:23:47 +0000 (03:23 +0000)
committerkcr <kcr@cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f>
Fri, 28 Dec 2007 03:23:47 +0000 (03:23 +0000)
git-svn-id: svn://svn.1ts.org/debian/branches/zephyr-reloaded@235 cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f

zephyr/server/bdump.c
zephyr/server/kstuff.c
zephyr/server/main.c

index ede9d034b1b48406b561e0de710772075334425d..0c3103e0fe834af8a1d5a3e814d0568cba3a8abd 100644 (file)
@@ -135,6 +135,7 @@ static int cancel_outgoing_dump;
 int bdumping;
 int bdump_concurrent;
 extern char *bdump_version;
+extern int bdump_auth_proto;
 
 /*
  * Functions for performing a brain dump between servers.
@@ -257,11 +258,25 @@ bdump_send()
 #ifdef _POSIX_VERSION
     struct sigaction action;
 #endif
-
+#if defined(HAVE_KRB4) || defined(HAVE_KRB5)
+    char *data = NULL;
+    int len = 0;
+    int proto = 0;
+#endif
 #ifdef HAVE_KRB4
     KTEXT_ST ticket;
     AUTH_DAT kdata;
-#else
+    /* may be moved into kstuff.c */
+    char instance [INST_SZ];
+#endif
+#ifdef HAVE_KRB5
+    /* may be moved into kstuff.c */
+    krb5_principal principal;
+    krb5_data k5data;
+    krb5_ap_rep_enc_part *rep;
+    krb5_keytab kt;
+#endif
+#if !defined(HAVE_KRB4) && !defined(HAVE_KRB5)
     unsigned short fromport;
 #endif /* HAVE_KRB4 */
  
@@ -316,21 +331,28 @@ bdump_send()
        bdump_socket = -1;
        timer_reset(bdump_timer);
     }
+
     /* Now begin the brain dump. */
-#ifdef HAVE_KRB5
-    { /* "server" side */
-       krb5_principal principal;
-       krb5_data data;
-       krb5_ap_rep_enc_part *rep;
-       krb5_keytab kt;
+#if defined(HAVE_KRB5) || defined(HAVE_KRB4)
+    retval = ReadKerberosData(live_socket, &len, &data, &proto);
 
-       if (get_tgt()) {
-           syslog(LOG_ERR, "bdump_send: get_tgt failed");
-           cleanup(server);
-           return;
-       }
+    if (retval != 0) {
+       syslog(LOG_ERR, "bdump_send: ReadKerberosData: %s",
+              krb_get_err_text(retval));
+       cleanup(server);
+       return;
+    }
+
+    if (get_tgt()) {
+       syslog(LOG_ERR, "bdump_send: get_tgt failed");
+       cleanup(server);
+       return;
+    }
  
+    switch(proto) {
+#ifdef HAVE_KRB5
+    case 5:
+       /* "server" side */
        retval = krb5_build_principal(Z_krb5_ctx, &principal, 
                                      strlen(ZGetRealm()),
                                      ZGetRealm(),
@@ -367,8 +389,9 @@ bdump_send()
 
        /* Get the "client" krb_ap_req */
 
-       memset((char *)&data, 0, sizeof(krb5_data));
-       retval = GetKrb5Data(live_socket, &data);
+       memset((char *)&k5data, 0, sizeof(krb5_data));
+       k5data.length = len;
+       k5data.data = data;
        if (retval) {
             syslog(LOG_ERR, "bdump_send: cannot get auth response: %s",
                    error_message(retval)); 
@@ -386,11 +409,11 @@ bdump_send()
            return;
        }
 
-       retval = krb5_rd_req(Z_krb5_ctx, &bdump_ac, &data, principal, kt, NULL, NULL);
+       retval = krb5_rd_req(Z_krb5_ctx, &bdump_ac, &k5data, principal, kt, NULL, NULL);
        krb5_free_principal(Z_krb5_ctx, principal);
        krb5_kt_close(Z_krb5_ctx, kt);
-       free(data.data);
-       memset((char *)&data, 0, sizeof(krb5_data));
+       free(k5data.data);
+       memset((char *)&k5data, 0, sizeof(krb5_data));
        if (retval) {
             syslog(LOG_ERR, "bdump_send: mutual authentication failed: %s",
                    error_message(retval));
@@ -400,64 +423,70 @@ bdump_send()
 
        /* Now send back our auth packet */
 
-       memset((char *)&data, 0, sizeof(krb5_data));
-       retval = krb5_mk_rep(Z_krb5_ctx, bdump_ac, &data);
+       retval = krb5_mk_rep(Z_krb5_ctx, bdump_ac, &k5data);
        if (retval) {
            syslog(LOG_ERR, "bdump_send: krb5_mk_rep: %s", error_message(retval));
            cleanup(server);
            return;
        }
-       retval = SendKrb5Data(live_socket, &data);
+       retval = SendKrb5Data(live_socket, &k5data);
        if (retval) {
             syslog(LOG_ERR, "bdump_send: cannot send authenticator: %s",
                    error_message(retval));
-            krb5_free_data_contents(Z_krb5_ctx, &data);
+            krb5_free_data_contents(Z_krb5_ctx, &k5data);
             cleanup(server);
             return;
        }    
-       krb5_free_data_contents(Z_krb5_ctx, &data);
-    }
-#else  /* HAVE_KRB5 */  
+       krb5_free_data_contents(Z_krb5_ctx, &k5data);
+       break;
+#endif  /* HAVE_KRB5 */  
 #ifdef HAVE_KRB4
-    /* receive the authenticator */
-    retval = GetKerberosData(live_socket, from.sin_addr, &kdata,
-                            SERVER_SERVICE, srvtab_file);
-    if (retval != KSUCCESS) {
-       syslog(LOG_ERR, "bdump_send: getkdata: %s",
-              krb_get_err_text(retval));
-       cleanup(server);
-       return;
-    }
-    if (get_tgt()) {
-       cleanup(server);
-       return;
-    }
-    if (strcmp(kdata.pname, SERVER_SERVICE) ||
-       strcmp(kdata.pinst, SERVER_INSTANCE) ||
-       strcmp(kdata.prealm, ZGetRealm())) {
-       syslog(LOG_ERR, "bdump_send: peer not zephyr: %s.%s@%s",
-              kdata.pname, kdata.pinst, kdata.prealm);
-       cleanup(server);
-       return;
-    }
-    /* authenticate back */
-    retval = SendKerberosData(live_socket, &ticket, SERVER_SERVICE,
-                             SERVER_INSTANCE);
-    if (retval != 0) {
-       syslog(LOG_ERR,"bdump_send: SendKerberosData: %s",
-              error_message (retval));
-       cleanup(server);
-       return;
+    case 4:
+       /* here to krb_rd_req from GetKerberosData candidate for refactoring
+          back into kstuff.c */
+       (void) strcpy(instance, "*");           /* let Kerberos fill it in */
+
+       ticket.length = len;
+       memcpy(&ticket.dat, data, MIN(len, sizeof(ticket.dat)));
+       retval = krb_rd_req(&ticket, SERVER_SERVICE, instance,
+                           from.sin_addr.s_addr, &kdata, srvtab_file);
+       /*
+       retval = GetKerberosData(live_socket, from.sin_addr, &kdata,
+                                SERVER_SERVICE, srvtab_file);
+       */
+       if (retval != KSUCCESS) {
+           syslog(LOG_ERR, "bdump_send: getkdata: %s",
+                  krb_get_err_text(retval));
+           cleanup(server);
+           return;
+       }
+       if (strcmp(kdata.pname, SERVER_SERVICE) ||
+           strcmp(kdata.pinst, SERVER_INSTANCE) ||
+           strcmp(kdata.prealm, ZGetRealm())) {
+           syslog(LOG_ERR, "bdump_send: peer not zephyr: %s.%s@%s",
+                  kdata.pname, kdata.pinst, kdata.prealm);
+           cleanup(server);
+           return;
+       }
+       /* authenticate back */
+       retval = SendKerberosData(live_socket, &ticket, SERVER_SERVICE,
+                                 SERVER_INSTANCE);
+       if (retval != 0) {
+           syslog(LOG_ERR,"bdump_send: SendKerberosData: %s",
+                  error_message (retval));
+           cleanup(server);
+           return;
+       }
+       break;
+#endif /* HAVE_KRB4 */
     }
-#else  /* !HAVE_KRB4 */
+#else /* HAVE_KRB4 || HAVE_KRB5 */
     if (fromport > IPPORT_RESERVED || fromport < IPPORT_RESERVED / 2) {
        syslog(LOG_ERR, "bdump_send: bad port from peer: %d", fromport);
        cleanup(server);
        return;
     }
-#endif /* HAVE_KRB4 */
-#endif /* HAVE_KRB5 */    
-
+#endif /* HAVE_KRB4 || HAVE_KRB5 */
     retval = setup_file_pointers();
     if (retval != 0) {
        syslog (LOG_WARNING, "bdump_send: can't set up file pointers: %s",
@@ -520,12 +549,21 @@ bdump_get_v12 (notice, auth, who, server)
 #ifdef _POSIX_VERSION
     struct sigaction action;
 #endif
+#if defined(HAVE_KRB4) || defined(HAVE_KRB5)
+#ifdef HAVE_KRB5
+    krb5_creds creds;
+    krb5_creds *credsp;
+    krb5_principal principal;
+    krb5_data data;
+    krb5_ap_rep_enc_part *rep;
+#endif
 #ifdef HAVE_KRB4
     KTEXT_ST ticket;
     AUTH_DAT kdata;
-#else  /* !HAVE_KRB4 */
+#endif
+#else  /* !HAVE_KRB4 && !HAVE_KRB5 */
     int reserved_port = IPPORT_RESERVED - 1;
-#endif /* HAVE_KRB4 */
+#endif /* !HAVE_KRB4 && !HAVE_KRB5 */
     
     bdumping = 1;
     server->dumping = 1;
@@ -565,7 +603,7 @@ bdump_get_v12 (notice, auth, who, server)
        server->dumping = 0;
        return;
     }
-#ifndef HAVE_KRB4
+#if !defined(HAVE_KRB4) && !defined(HAVE_KRB5)
     if (ntohs(from.sin_port) > IPPORT_RESERVED ||
        ntohs(from.sin_port) < IPPORT_RESERVED / 2) {
        syslog(LOG_ERR, "bdump_get: port not reserved: %d",
@@ -574,9 +612,9 @@ bdump_get_v12 (notice, auth, who, server)
        return;
     }
     live_socket = rresvport(&reserved_port);
-#else  /* !HAVE_KRB4 */
+#else  /* !HAVE_KRB4 && !HAVE_KRB5 */
     live_socket = socket(AF_INET, SOCK_STREAM, 0);
-#endif /* HAVE_KRB4 */
+#endif /* !HAVE_KRB4 && !HAVE_KRB5 */
     if (live_socket < 0) {
        syslog(LOG_ERR, "bdump_get: socket: %m");
        cleanup(server);
@@ -595,21 +633,16 @@ bdump_get_v12 (notice, auth, who, server)
 #endif
  
     /* Now begin the brain dump. */
-
-#ifdef HAVE_KRB5
+#if defined(HAVE_KRB4) || defined(HAVE_KRB5)
     if (get_tgt()) {
        syslog(LOG_ERR, "bdump_get: get_tgt failed"); 
        cleanup(server);
        return;
     }
-    { /* "client" side */
-       krb5_creds creds;
-       krb5_creds *credsp;
-       krb5_principal principal;
-       krb5_data data;
-        krb5_ap_rep_enc_part *rep;
-       memset((char *)&creds, 0, sizeof(creds));
+    switch(bdump_auth_proto) {
+#ifdef HAVE_KRB5
+    case 5: /* "client" side */
+       memset((char *)&creds, 0, sizeof(creds));
 
        retval = krb5_build_principal(Z_krb5_ctx, &principal, 
                                      strlen(ZGetRealm()),
@@ -709,45 +742,41 @@ bdump_get_v12 (notice, auth, who, server)
              cleanup(server);
              return;
         }    
-
-    }
-#else    
-#ifdef HAVE_KRB4
-    /* send an authenticator */
-    if (get_tgt()) {
-       cleanup(server);
-       return;
-    }
-    retval = SendKerberosData(live_socket, &ticket, SERVER_SERVICE,
-                             SERVER_INSTANCE);
-    if (retval != 0) {
-       syslog(LOG_ERR,"bdump_get: %s", error_message(retval));
-       cleanup(server);
-       return;
-    }
-#if 1
-    zdbug((LOG_DEBUG, "bdump_get: SendKerberosData ok"));
+       break;
 #endif
-    /* get his authenticator */
-    retval = GetKerberosData(live_socket, from.sin_addr, &kdata,
-                            SERVER_SERVICE, srvtab_file);
-    if (retval != KSUCCESS) {
-       syslog(LOG_ERR, "bdump_get getkdata: %s",krb_get_err_text(retval));
-       cleanup(server);
-       return;
-    }
+#ifdef HAVE_KRB4
+    case 4:
+       /* send an authenticator */
+       retval = SendKerberosData(live_socket, &ticket, SERVER_SERVICE,
+                                 SERVER_INSTANCE);
+       if (retval != 0) {
+           syslog(LOG_ERR,"bdump_get: %s", error_message(retval));
+           cleanup(server);
+           return;
+       }
+       zdbug((LOG_DEBUG, "bdump_get: SendKerberosData ok"));
+       
+       /* get his authenticator */
+       retval = GetKerberosData(live_socket, from.sin_addr, &kdata,
+                                SERVER_SERVICE, srvtab_file);
+       if (retval != KSUCCESS) {
+           syslog(LOG_ERR, "bdump_get getkdata: %s",krb_get_err_text(retval));
+           cleanup(server);
+           return;
+       }
 
-    if (strcmp(kdata.pname, SERVER_SERVICE) ||
-       strcmp(kdata.pinst, SERVER_INSTANCE) ||
-       strcmp(kdata.prealm, ZGetRealm())) {
-       syslog(LOG_ERR, "bdump_get: peer not zephyr in lrealm: %s.%s@%s",
-              kdata.pname, kdata.pinst,kdata.prealm);
-       cleanup(server);
-       return;
-    }
+       if (strcmp(kdata.pname, SERVER_SERVICE) ||
+           strcmp(kdata.pinst, SERVER_INSTANCE) ||
+           strcmp(kdata.prealm, ZGetRealm())) {
+           syslog(LOG_ERR, "bdump_get: peer not zephyr in lrealm: %s.%s@%s",
+                  kdata.pname, kdata.pinst,kdata.prealm);
+           cleanup(server);
+           return;
+       }
+       break;
 #endif /* HAVE_KRB4 */
-#endif    
+    }
+#endif /* defined(HAVE_KRB4) || defined(HAVE_KRB5) */   
     retval = setup_file_pointers();
     if (retval != 0) {
        syslog(LOG_WARNING, "bdump_get: can't set up file pointers: %s",
@@ -762,9 +791,7 @@ bdump_get_v12 (notice, auth, who, server)
        cleanup(server);
        return;
     }
-#if 1
     zdbug((LOG_DEBUG,"bdump_get: gbdl ok"));
-#endif
     retval = bdump_send_loop(server);
     if (retval != ZERR_NONE) {
        syslog(LOG_WARNING, "bdump_send_loop failed: %s",
index 7d4d8adc277cfb63fe48548edd2e7c9561206f8e..5d839651b4bb26db46228c3a0271fad290964c82 100644 (file)
@@ -122,6 +122,68 @@ SendKerberosData(fd, ticket, service, host)
 
 #endif /* HAVE_KRB4 */
 
+#if defined(HAVE_KRB5) || defined(HAVE_KRB4)
+Code_t
+ReadKerberosData(int fd, int *size, char **data, int *proto) {
+    char p[20];
+    int i;
+    unsigned char *dst;
+    Code_t retval;
+    int len = 0;
+
+    for (i=0; i<20; i++) {
+       if (read(fd, &p[i], 1) != 1) {
+           p[i] = 0;
+           syslog(LOG_WARNING,"ReadKerberosData: bad read reply len @%d (got \"%s\"", i, p);
+           return(KFAILURE);
+       }
+       if (p[i] == ' ') {
+           p[i] = '\0';
+           break;
+       }
+    }
+
+    if (i == 20) {
+       syslog(LOG_WARNING, "ReadKerberosData: read reply len exceeds buffer");
+           return KFAILURE;
+    }
+
+    if (!strncmp(p, "V5-", 3) && (len = atoi(p+3)) > 0)
+       *proto = 5;
+    else if ((len = atoi(p)) > 0)
+       *proto = 4;
+
+    if (*proto < 4 | *proto > 5) {
+       syslog(LOG_WARNING, "ReadKerberosData: error parsing authenticator length (\"%s\")", p);
+       return KFAILURE;
+    }
+
+    if (len <= 0) {
+       syslog(LOG_WARNING, "ReadKerberosData: read reply len = %d", len);
+       return KFAILURE;
+    }
+
+    *data = malloc(len);
+    if (! *data) {
+       syslog(LOG_WARNING, "ReadKerberosData: failure allocating %d bytes: %m", len);
+       return errno;
+    }
+    
+    dst=*data;
+    for (i=0; i < len; i++) {
+       if (read(fd, dst++, 1) != 1) {
+            free(*data);
+           *data = NULL;
+           *size = 0;
+            syslog(LOG_WARNING,"ReadKerberosData: bad read reply string");
+            return ZSRV_PKSHORT;
+        }
+    }
+    *size = len;
+    return 0;
+}
+#endif
+
 #ifdef HAVE_KRB5
 Code_t
 GetKrb5Data(int fd, krb5_data *data) {
@@ -162,6 +224,7 @@ GetKrb5Data(int fd, krb5_data *data) {
     }
     return 0;
 }
+
 Code_t
 SendKrb5Data(int fd, krb5_data *data) {
     char p[32];
index 88245dad9d70438adffa7bd6a1d767eb05ba9d06..1e2bb7ce2b1da81cb62a32258ac7fdd516f02927 100644 (file)
@@ -124,6 +124,16 @@ static int nofork;
 struct in_addr my_addr;
 char *bdump_version = "1.2";
 
+#ifdef HAVE_KRB5
+int bdump_auth_proto = 5;
+#else /* HAVE_KRB5 */
+#ifdef HAVE_KRB4
+int bdump_auth_proto = 4;
+#else /* HAVE_KRB4 */
+int bdump_auth_proto = 0;
+#endif /* HAVE_KRB4 */
+#endif /* HAVE_KRB5 */
+
 #ifdef HAVE_KRB5
 krb5_ccache Z_krb5_ccache;
 krb5_keyblock *__Zephyr_keyblock;
@@ -167,7 +177,7 @@ main(argc, argv)
     programname = (programname) ? programname + 1 : argv[0];
 
     /* process arguments */
-    while ((optchar = getopt(argc, argv, "dsnv:f:k:")) != EOF) {
+    while ((optchar = getopt(argc, argv, "dsnv4:f:k:")) != EOF) {
        switch(optchar) {
          case 'd':
            zdebug = 1;
@@ -192,6 +202,9 @@ main(argc, argv)
            init_from_dump = 0;
            dumpfile = optarg;
            break;
+       case '4':
+           bdump_auth_proto = 4;
+           break;
          case '?':
          default:
            usage();