/* * Now we send over the database. We use the following protocol: * Send over a KRB_SAFE message with the size. Then we send over the * database in blocks of KPROP_BLKSIZE, encrypted using KRB_PRIV. * Then we expect to see a KRB_SAFE message with the size sent back. * * At any point in the protocol, we may send a KRB_ERROR message; this * will abort the entire operation. */ static void xmit_database(krb5_context context, krb5_auth_context auth_context, krb5_creds *my_creds, int fd, int database_fd, int in_database_size) { krb5_int32 n; krb5_data inbuf, outbuf; char buf[KPROP_BUFSIZ]; krb5_error_code retval; krb5_error *error; krb5_ui_4 database_size = in_database_size, send_size, sent_size; /* Send over the size. */ send_size = htonl(database_size); inbuf.data = (char *)&send_size; inbuf.length = sizeof(send_size); /* must be 4, really */ /* KPROP_CKSUMTYPE */ retval = krb5_mk_safe(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { com_err(progname, retval, _("while encoding database size")); send_error(context, my_creds, fd, _("while encoding database size"), retval); exit(1); } retval = krb5_write_message(context, &fd, &outbuf); if (retval) { krb5_free_data_contents(context, &outbuf); com_err(progname, retval, _("while sending database size")); exit(1); } krb5_free_data_contents(context, &outbuf); /* Initialize the initial vector. */ retval = krb5_auth_con_initivector(context, auth_context); if (retval) { send_error(context, my_creds, fd, "failed while initializing i_vector", retval); com_err(progname, retval, _("while allocating i_vector")); exit(1); } /* Send over the file, block by block. */ inbuf.data = buf; sent_size = 0; while ((n = read(database_fd, buf, sizeof(buf)))) { inbuf.length = n; retval = krb5_mk_priv(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { snprintf(buf, sizeof(buf), "while encoding database block starting at %d", sent_size); com_err(progname, retval, "%s", buf); send_error(context, my_creds, fd, buf, retval); exit(1); } retval = krb5_write_message(context, &fd, &outbuf); if (retval) { krb5_free_data_contents(context, &outbuf); com_err(progname, retval, _("while sending database block starting at %d"), sent_size); exit(1); } krb5_free_data_contents(context, &outbuf); sent_size += n; if (debug) printf("%d bytes sent.\n", sent_size); } if (sent_size != database_size) { com_err(progname, 0, _("Premature EOF found for database file!")); send_error(context, my_creds, fd, "Premature EOF found for database file!", KRB5KRB_ERR_GENERIC); exit(1); } /* * OK, we've sent the database; now let's wait for a success * indication from the remote end. */ retval = krb5_read_message(context, &fd, &inbuf); if (retval) { com_err(progname, retval, _("while reading response from server")); exit(1); } /* * If we got an error response back from the server, display * the error message */ if (krb5_is_krb_error(&inbuf)) { retval = krb5_rd_error(context, &inbuf, &error); if (retval) { com_err(progname, retval, _("while decoding error response from server")); exit(1); } if (error->error == KRB_ERR_GENERIC) { if (error->text.data) { fprintf(stderr, _("Generic remote error: %s\n"), error->text.data); } } else if (error->error) { com_err(progname, (krb5_error_code)error->error + ERROR_TABLE_BASE_krb5, _("signalled from server")); if (error->text.data) { fprintf(stderr, _("Error text from server: %s\n"), error->text.data); } } krb5_free_error(context, error); exit(1); } retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL); if (retval) { com_err(progname, retval, "while decoding final size packet from server"); exit(1); } memcpy(&send_size, outbuf.data, sizeof(send_size)); send_size = ntohl(send_size); if (send_size != database_size) { com_err(progname, 0, _("Kpropd sent database size %d, expecting %d"), send_size, database_size); exit(1); } free(outbuf.data); }
/* * Serialize krb5_auth_context. */ static krb5_error_code ser_acontext_test(krb5_context kcontext, int verbose) { krb5_error_code kret; krb5_auth_context actx; krb5_address local_address; krb5_address remote_address; krb5_octet laddr_bytes[16]; krb5_octet raddr_bytes[16]; krb5_keyblock ukeyblock; krb5_octet keydata[8]; krb5_authenticator aent; char clname[128]; krb5_authdata *adatalist[3]; krb5_authdata adataent; actx = (krb5_auth_context) NULL; if (!(kret = krb5_auth_con_init(kcontext, &actx)) && !(kret = ser_data(verbose, "> Vanilla auth context", (krb5_pointer) actx, KV5M_AUTH_CONTEXT))) { memset(&local_address, 0, sizeof(local_address)); memset(&remote_address, 0, sizeof(remote_address)); memset(laddr_bytes, 0, sizeof(laddr_bytes)); memset(raddr_bytes, 0, sizeof(raddr_bytes)); local_address.addrtype = ADDRTYPE_INET; local_address.length = sizeof(laddr_bytes); local_address.contents = laddr_bytes; laddr_bytes[0] = 6; laddr_bytes[1] = 2; laddr_bytes[2] = 69; laddr_bytes[3] = 16; laddr_bytes[4] = 1; laddr_bytes[5] = 0; laddr_bytes[6] = 0; laddr_bytes[7] = 127; remote_address.addrtype = ADDRTYPE_INET; remote_address.length = sizeof(raddr_bytes); remote_address.contents = raddr_bytes; raddr_bytes[0] = 6; raddr_bytes[1] = 2; raddr_bytes[2] = 70; raddr_bytes[3] = 16; raddr_bytes[4] = 1; raddr_bytes[5] = 0; raddr_bytes[6] = 0; raddr_bytes[7] = 127; if (!(kret = krb5_auth_con_setaddrs(kcontext, actx, &local_address, &remote_address)) && !(kret = krb5_auth_con_setports(kcontext, actx, &local_address, &remote_address)) && !(kret = ser_data(verbose, "> Auth context with addrs/ports", (krb5_pointer) actx, KV5M_AUTH_CONTEXT))) { memset(&ukeyblock, 0, sizeof(ukeyblock)); memset(keydata, 0, sizeof(keydata)); ukeyblock.enctype = ENCTYPE_DES_CBC_MD5; ukeyblock.length = sizeof(keydata); ukeyblock.contents = keydata; keydata[0] = 0xde; keydata[1] = 0xad; keydata[2] = 0xbe; keydata[3] = 0xef; keydata[4] = 0xfe; keydata[5] = 0xed; keydata[6] = 0xf0; keydata[7] = 0xd; if (!(kret = krb5_auth_con_setuseruserkey(kcontext, actx, &ukeyblock)) && !(kret = ser_data(verbose, "> Auth context with user key", (krb5_pointer) actx, KV5M_AUTH_CONTEXT)) && !(kret = krb5_auth_con_initivector(kcontext, actx)) && !(kret = ser_data(verbose, "> Auth context with new vector", (krb5_pointer) actx, KV5M_AUTH_CONTEXT)) && (krb5_xfree(actx->i_vector), actx->i_vector) && !(kret = krb5_auth_con_setivector(kcontext, actx, (krb5_pointer) print_erep) ) && !(kret = ser_data(verbose, "> Auth context with set vector", (krb5_pointer) actx, KV5M_AUTH_CONTEXT))) { /* * Finally, add an authenticator. */ memset(&aent, 0, sizeof(aent)); aent.magic = KV5M_AUTHENTICATOR; snprintf(clname, sizeof(clname), "help/me/%[email protected]", (int) getpid()); actx->authentp = &aent; if (!(kret = krb5_parse_name(kcontext, clname, &aent.client)) && !(kret = ser_data(verbose, "> Auth context with authenticator", (krb5_pointer) actx, KV5M_AUTH_CONTEXT))) { adataent.magic = KV5M_AUTHDATA; adataent.ad_type = 123; adataent.length = 128; adataent.contents = (krb5_octet *) stuff; adatalist[0] = &adataent; adatalist[1] = &adataent; adatalist[2] = (krb5_authdata *) NULL; aent.authorization_data = adatalist; if (!(kret = ser_data(verbose, "> Auth context with full auth", (krb5_pointer) actx, KV5M_AUTH_CONTEXT))) { if (verbose) printf("* krb5_auth_context test succeeded\n"); } krb5_free_principal(kcontext, aent.client); } actx->authentp = (krb5_authenticator *) NULL; } } } if (actx) krb5_auth_con_free(kcontext, actx); if (kret) printf("* krb5_auth_context test failed\n"); return(kret); }