alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Ktab.java)

This example Java source code file (Ktab.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

bufferedreader, default, deletion, ioexception, key, krbexception, ktab, kvno, numberformatexception, numbers, principalname, string, text, util

The Ktab.java Java example source code

/*
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 *  (C) Copyright IBM Corp. 1999 All Rights Reserved.
 *  Copyright 1997 The Open Group Research Institute.  All rights reserved.
 */

package sun.security.krb5.internal.tools;

import sun.security.krb5.*;
import sun.security.krb5.internal.ktab.*;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.File;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import sun.security.krb5.internal.crypto.EType;
/**
 * This class can execute as a command-line tool to help the user manage
 * entries in the key table.
 * Available functions include list/add/update/delete service key(s).
 *
 * @author Yanni Zhang
 * @author Ram Marti
 */

public class Ktab {
    // KeyTabAdmin admin;
    KeyTab table;
    char action;
    String name;   // name and directory of key table
    String principal;
    boolean showEType;
    boolean showTime;
    int etype = -1;
    char[] password = null;

    boolean forced = false; // true if delete without prompt. Default false
    boolean append = false; // true if new keys are appended. Default false
    int vDel = -1;          // kvno to delete, -1 all, -2 old. Default -1
    int vAdd = -1;          // kvno to add. Default -1, means auto incremented

    /**
     * The main program that can be invoked at command line.
     * See {@link #printHelp} for usages.
     */
    public static void main(String[] args) {
        Ktab ktab = new Ktab();
        if ((args.length == 1) && (args[0].equalsIgnoreCase("-help"))) {
            ktab.printHelp();
            return;
        } else if ((args == null) || (args.length == 0)) {
            ktab.action = 'l';
        } else {
            ktab.processArgs(args);
        }
        ktab.table = KeyTab.getInstance(ktab.name);
        if (ktab.table.isMissing() && ktab.action != 'a') {
            if (ktab.name == null) {
                System.out.println("No default key table exists.");
            } else {
                System.out.println("Key table " +
                        ktab.name + " does not exist.");
            }
            System.exit(-1);
        }
        if (!ktab.table.isValid()) {
            if (ktab.name == null) {
                System.out.println("The format of the default key table " +
                        " is incorrect.");
            } else {
                System.out.println("The format of key table " +
                        ktab.name + " is incorrect.");
            }
            System.exit(-1);
        }
        switch (ktab.action) {
        case 'l':
            ktab.listKt();
            break;
        case 'a':
            ktab.addEntry();
            break;
        case 'd':
            ktab.deleteEntry();
            break;
        default:
            ktab.error("A command must be provided");
        }
    }

    /**
     * Parses the command line arguments.
     */
    void processArgs(String[] args) {

        // Commands (should appear before options):
        //   -l
        //   -a <princ>
        //   -d <princ>
        // Options:
        //   -e <etype> (for -d)
        //   -e (for -l)
        //   -n <kvno>
        //   -k <keytab>
        //   -t
        //   -f
        //   -append
        // Optional extra arguments:
        //   password for -a
        //   [kvno|all|old] for -d

        boolean argAlreadyAppeared = false;
        for (int i = 0; i < args.length; i++) {
            if (args[i].startsWith("-")) {
                switch (args[i].toLowerCase(Locale.US)) {

                    // Commands
                    case "-l":   // list
                        action = 'l';
                        break;
                    case "-a":   // add a new entry to keytab.
                        action = 'a';
                        if (++i >= args.length || args[i].startsWith("-")) {
                            error("A principal name must be specified after -a");
                        }
                        principal = args[i];
                        break;
                    case "-d":   // delete entries
                        action = 'd';
                        if (++i >= args.length || args[i].startsWith("-")) {
                            error("A principal name must be specified after -d");
                        }
                        principal = args[i];
                        break;

                        // Options
                    case "-e":
                        if (action == 'l') {    // list etypes
                            showEType = true;
                        } else if (action == 'd') { // delete etypes
                            if (++i >= args.length || args[i].startsWith("-")) {
                                error("An etype must be specified after -e");
                            }
                            try {
                                etype = Integer.parseInt(args[i]);
                                if (etype <= 0) {
                                    throw new NumberFormatException();
                                }
                            } catch (NumberFormatException nfe) {
                                error(args[i] + " is not a valid etype");
                            }
                        } else {
                            error(args[i] + " is not valid after -" + action);
                        }
                        break;
                    case "-n":   // kvno for -a
                        if (++i >= args.length || args[i].startsWith("-")) {
                            error("A KVNO must be specified after -n");
                        }
                        try {
                            vAdd = Integer.parseInt(args[i]);
                            if (vAdd < 0) {
                                throw new NumberFormatException();
                            }
                        } catch (NumberFormatException nfe) {
                            error(args[i] + " is not a valid KVNO");
                        }
                        break;
                    case "-k":  // specify keytab to use
                        if (++i >= args.length || args[i].startsWith("-")) {
                            error("A keytab name must be specified after -k");
                        }
                        if (args[i].length() >= 5 &&
                            args[i].substring(0, 5).equalsIgnoreCase("FILE:")) {
                            name = args[i].substring(5);
                        } else {
                            name = args[i];
                        }
                        break;
                    case "-t":   // list timestamps
                        showTime = true;
                        break;
                    case "-f":   // force delete, no prompt
                        forced = true;
                        break;
                    case "-append": // -a, new keys append to file
                        append = true;
                        break;
                    default:
                        error("Unknown command: " + args[i]);
                        break;
                }
            } else {    // optional standalone arguments
                if (argAlreadyAppeared) {
                    error("Useless extra argument " + args[i]);
                }
                if (action == 'a') {
                    password = args[i].toCharArray();
                } else if (action == 'd') {
                    switch (args[i]) {
                        case "all": vDel = -1; break;
                        case "old": vDel = -2; break;
                        default: {
                            try {
                                vDel = Integer.parseInt(args[i]);
                                if (vDel < 0) {
                                    throw new NumberFormatException();
                                }
                            } catch (NumberFormatException nfe) {
                                error(args[i] + " is not a valid KVNO");
                            }
                        }
                    }
                } else {
                    error("Useless extra argument " + args[i]);
                }
                argAlreadyAppeared = true;
            }
        }
    }

    /**
     * Adds a service key to key table. If the specified key table does not
     * exist, the program will automatically generate
     * a new key table.
     */
    void addEntry() {
        PrincipalName pname = null;
        try {
            pname = new PrincipalName(principal);
        } catch (KrbException e) {
            System.err.println("Failed to add " + principal +
                               " to keytab.");
            e.printStackTrace();
            System.exit(-1);
        }
        if (password == null) {
            try {
                BufferedReader cis =
                    new BufferedReader(new InputStreamReader(System.in));
                System.out.print("Password for " + pname.toString() + ":");
                System.out.flush();
                password = cis.readLine().toCharArray();
            } catch (IOException e) {
                System.err.println("Failed to read the password.");
                e.printStackTrace();
                System.exit(-1);
            }

        }
        try {
            // admin.addEntry(pname, password);
            table.addEntry(pname, password, vAdd, append);
            Arrays.fill(password, '0');  // clear password
            // admin.save();
            table.save();
            System.out.println("Done!");
            System.out.println("Service key for " + principal +
                               " is saved in " + table.tabName());

        } catch (KrbException e) {
            System.err.println("Failed to add " + principal + " to keytab.");
            e.printStackTrace();
            System.exit(-1);
        } catch (IOException e) {
            System.err.println("Failed to save new entry.");
            e.printStackTrace();
            System.exit(-1);
        }
    }

    /**
     * Lists key table name and entries in it.
     */
    void listKt() {
        System.out.println("Keytab name: " + table.tabName());
        KeyTabEntry[] entries = table.getEntries();
        if ((entries != null) && (entries.length > 0)) {
            String[][] output = new String[entries.length+1][showTime?3:2];
            int column = 0;
            output[0][column++] = "KVNO";
            if (showTime) output[0][column++] = "Timestamp";
            output[0][column++] = "Principal";
            for (int i = 0; i < entries.length; i++) {
                column = 0;
                output[i+1][column++] = entries[i].getKey().
                        getKeyVersionNumber().toString();
                if (showTime) output[i+1][column++] =
                        DateFormat.getDateTimeInstance(
                        DateFormat.SHORT, DateFormat.SHORT).format(
                        new Date(entries[i].getTimeStamp().getTime()));
                String princ = entries[i].getService().toString();
                if (showEType) {
                    int e = entries[i].getKey().getEType();
                    output[i+1][column++] = princ + " (" + e + ":" +
                            EType.toString(e) + ")";
                } else {
                    output[i+1][column++] = princ;
                }
            }
            int[] width = new int[column];
            for (int j=0; j<column; j++) {
                for (int i=0; i <= entries.length; i++) {
                    if (output[i][j].length() > width[j]) {
                        width[j] = output[i][j].length();
                    }
                }
                if (j != 0) width[j] = -width[j];
            }
            for (int j=0; j<column; j++) {
                System.out.printf("%" + width[j] + "s ", output[0][j]);
            }
            System.out.println();
            for (int j=0; j<column; j++) {
                for (int k=0; k<Math.abs(width[j]); k++) System.out.print("-");
                System.out.print(" ");
            }
            System.out.println();
            for (int i=0; i<entries.length; i++) {
                for (int j=0; j<column; j++) {
                    System.out.printf("%" + width[j] + "s ", output[i+1][j]);
                }
                System.out.println();
            }
        } else {
            System.out.println("0 entry.");
        }
    }

    /**
     * Deletes an entry from the key table.
     */
    void deleteEntry() {
        PrincipalName pname = null;
        try {
            pname = new PrincipalName(principal);
            if (!forced) {
                String answer;
                BufferedReader cis =
                    new BufferedReader(new InputStreamReader(System.in));
                System.out.print("Are you sure you want to delete "+
                        "service key(s) for " + pname.toString() +
                        " (" + (etype==-1?"all etypes":("etype="+etype)) + ", " +
                        (vDel==-1?"all kvno":(vDel==-2?"old kvno":("kvno=" + vDel))) +
                        ") in " + table.tabName() + "? (Y/[N]): ");

                System.out.flush();
                answer = cis.readLine();
                if (answer.equalsIgnoreCase("Y") ||
                    answer.equalsIgnoreCase("Yes"));
                else {
                    // no error, the user did not want to delete the entry
                    System.exit(0);
                }
            }
        } catch (KrbException e) {
            System.err.println("Error occurred while deleting the entry. "+
                               "Deletion failed.");
            e.printStackTrace();
            System.exit(-1);
        } catch (IOException e) {
            System.err.println("Error occurred while deleting the entry. "+
                               " Deletion failed.");
            e.printStackTrace();
            System.exit(-1);
        }

        int count = table.deleteEntries(pname, etype, vDel);

        if (count == 0) {
            System.err.println("No matched entry in the keytab. " +
                               "Deletion fails.");
            System.exit(-1);
        } else {
            try {
                table.save();
            } catch (IOException e) {
                System.err.println("Error occurs while saving the keytab. " +
                                   "Deletion fails.");
                e.printStackTrace();
                System.exit(-1);
            }
            System.out.println("Done! " + count + " entries removed.");
        }
    }

    void error(String... errors) {
        for (String error: errors) {
            System.out.println("Error: " + error + ".");
        }
        printHelp();
        System.exit(-1);
    }
    /**
     * Prints out the help information.
     */
    void printHelp() {
        System.out.println("\nUsage: ktab <commands> ");
        System.out.println();
        System.out.println("Available commands:");
        System.out.println();
        System.out.println("-l [-e] [-t]\n"
                + "    list the keytab name and entries. -e with etype, -t with timestamp.");
        System.out.println("-a <principal name> [] [-n ] [-append]\n"
                + "    add new key entries to the keytab for the given principal name with\n"
                + "    optional <password>. If a  is specified, new keys' Key Version\n"
                + "    Numbers equal to the value, otherwise, automatically incrementing\n"
                + "    the Key Version Numbers. If -append is specified, new keys are\n"
                + "    appended to the keytab, otherwise, old keys for the\n"
                + "    same principal are removed.");
        System.out.println("-d <principal name> [-f] [-e ] [ | all | old]\n"
                + "    delete key entries from the keytab for the specified principal. If\n"
                + "    <kvno> is specified, delete keys whose Key Version Numbers match\n"
                + "    kvno. If \"all\" is specified, delete all keys. If \"old\" is specified,\n"
                + "    delete all keys except those with the highest kvno. Default action\n"
                + "    is \"all\". If <etype> is specified, only keys of this encryption type\n"
                + "    are deleted. <etype> should be specified as the numberic value etype\n"
                + "    defined in RFC 3961, section 8. A prompt to confirm the deletion is\n"
                + "    displayed unless -f is specified.");
        System.out.println();
        System.out.println("Common option(s):");
        System.out.println();
        System.out.println("-k <keytab name>\n"
                + "    specify keytab name and path with prefix FILE:");
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Ktab.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.