Exemple #1
0
/*
 * 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);
}
Exemple #2
0
/* 
 * 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);
}