Blame SOURCES/keyrand.c

9fa50b
/* 
9fa50b
   keyrand implementation using /dev/random
9fa50b
   Copyright (C) 2006 Red Hat, Inc.
9fa50b
9fa50b
   This program is free software; you can redistribute it and/or modify
9fa50b
   it under the terms of the GNU General Public License as published by
9fa50b
   the Free Software Foundation; either version 2 of the License, or
9fa50b
   (at your option) any later version.
9fa50b
  
9fa50b
   This program is distributed in the hope that it will be useful,
9fa50b
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9fa50b
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9fa50b
   GNU General Public License for more details.
9fa50b
  
9fa50b
   You should have received a copy of the GNU General Public License
9fa50b
   along with this program; if not, write to the Free Software
9fa50b
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
9fa50b
9fa50b
*/
9fa50b
9fa50b
#include <sys/types.h>
9fa50b
9fa50b
#include <unistd.h>
9fa50b
#include <string.h>
9fa50b
#include <stdio.h>
9fa50b
#include <fcntl.h>
9fa50b
#include <errno.h>
9fa50b
#include <stdlib.h>
9fa50b
9fa50b
#include <slang/slang.h>
9fa50b
#include <newt.h>
9fa50b
9fa50b
static void collect_bytes(int fd, char *buffer, int total)
9fa50b
{
9fa50b
    int count;
9fa50b
    newtComponent title, form, scale;
9fa50b
    char message[1024];
9fa50b
    newtGrid box;
9fa50b
9fa50b
    box = newtCreateGrid(1, 3);
9fa50b
9fa50b
    snprintf(message, sizeof message,
9fa50b
             "To generate %u random bits from the "
9fa50b
             "kernel random number generator, some "
9fa50b
             "keyboard or mouse input may be necessary at the "
9fa50b
             "console for this host.  Please try entering "
9fa50b
             "some random text or moving the mouse, if "
9fa50b
             "running this program locally.", total * 8);
9fa50b
    
9fa50b
    title = newtTextboxReflowed(1, 1, message, 60, 10, 0, 0);
9fa50b
    
9fa50b
    newtGridSetField(box, 0, 0, NEWT_GRID_COMPONENT, title,
9fa50b
		     0, 0, 0, 0, 0, 0);
9fa50b
    
9fa50b
    /* The progress bar */
9fa50b
    scale = newtScale(0, 0, 30, total);
9fa50b
    newtScaleSet(scale, 0);
9fa50b
    
9fa50b
    newtGridSetField(box, 0, 1, NEWT_GRID_COMPONENT, scale,
9fa50b
		     0, 1, 0, 0, 0, 0);
9fa50b
9fa50b
    form = newtForm(NULL, NULL, 0);
9fa50b
    newtGridAddComponentsToForm(box, form, 1);
9fa50b
    
9fa50b
    newtGridWrappedWindow(box, "Collecting random data");
9fa50b
    
9fa50b
    newtDrawForm(form);
9fa50b
9fa50b
    count = 0;
9fa50b
9fa50b
    do {
9fa50b
        ssize_t rv;
9fa50b
        
9fa50b
        newtScaleSet(scale, count);
9fa50b
        newtRefresh();
9fa50b
9fa50b
        rv = read(fd, buffer + count, total - count);
9fa50b
        if (rv == -1 && errno == EINTR) continue;
9fa50b
        else if (rv < 0) {
9fa50b
            newtWinMessage("Error", "Exit", 
9fa50b
                           "Error reading from /dev/random");
9fa50b
            newtFinished();
9fa50b
            exit(1);
9fa50b
        }
9fa50b
9fa50b
	SLang_flush_input();
9fa50b
        count += rv;
9fa50b
    } while (count < total);
9fa50b
9fa50b
    newtFormDestroy(form);
9fa50b
}
9fa50b
    
9fa50b
9fa50b
int main(int argc, char **argv)
9fa50b
{
9fa50b
    const char *output;
9fa50b
    int bits, bytes, fd, rfd;
9fa50b
    char *buffer;
9fa50b
9fa50b
    if (argc < 3) {
9fa50b
        fprintf(stderr, "Usage: keyrand <number-of-bits> <output-file>\n");
9fa50b
        exit(1);
9fa50b
    }
9fa50b
    
9fa50b
    bits = atoi(argv[1]);
9fa50b
    output = argv[2];
9fa50b
    fd = open(output, O_APPEND|O_WRONLY);
9fa50b
    rfd = open("/dev/random", O_RDONLY);
9fa50b
    
9fa50b
    newtInit();
9fa50b
    newtCls();
9fa50b
    
9fa50b
    newtDrawRootText(0, 0, 
9fa50b
                     "Red Hat Keypair Generation (c) 2006 Red Hat, Inc.");
9fa50b
    
9fa50b
    if (fd < 0) {
9fa50b
        newtWinMessage("Error", "Exit", "Could not open output file");
9fa50b
        newtFinished();
9fa50b
        exit(1);
9fa50b
    }
9fa50b
    else if (rfd < 0) {
9fa50b
        newtWinMessage("Error", "Exit", "Could not open /dev/random");
9fa50b
        newtFinished();
9fa50b
        exit(1);
9fa50b
    }
9fa50b
    else if (bits < 8 || bits > 800 * 1024) {
9fa50b
        newtWinMessage("Error", "Exit", "More than 8 bits must be requested");
9fa50b
        newtFinished();
9fa50b
        exit(1);
9fa50b
    }
9fa50b
    
9fa50b
    bytes = bits / 8;
9fa50b
    buffer = malloc(bytes);
9fa50b
    sleep(1);
9fa50b
9fa50b
    collect_bytes(rfd, buffer, bytes);
9fa50b
    
9fa50b
    if (write(fd, buffer, bytes) != bytes || close(fd)) {
9fa50b
        newtWinMessage("Error", "Exit", "Error writing to random file");
9fa50b
        newtFinished();
9fa50b
        exit(1);
9fa50b
    }
9fa50b
9fa50b
    newtFinished();
9fa50b
    
9fa50b
    newtRefresh();
9fa50b
9fa50b
    sleep(1);
9fa50b
    newtPopWindow();
9fa50b
    SLang_flush_input();
9fa50b
    newtClearKeyBuffer();
9fa50b
9fa50b
    return 0;
9fa50b
}
9fa50b