Commit 97c9659e authored by Niels Möller's avatar Niels Möller
Browse files

*** empty log message ***

Rev: src/lsh_writekey.c:1.1
Rev: src/sexp_test.c:1.3
parent d3c6959d
/* lsh_writekey.c
*
* Reads a (private) key on stdin, and saves it a private and a public file.
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "blocking_write.h"
#include "format.h"
#include "io.h"
#include "sexp.h"
#include "werror.h"
#include "xalloc.h"
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "lsh_writekey.c.x"
/* FIXME: Should support encryption of the private key. */
static struct sexp *dss_private2public(struct sexp_iterator *i)
{
struct sexp *p;
struct sexp *q;
struct sexp *g;
struct sexp *y;
struct sexp *x;
p = SEXP_GET(i);
if (!(p && sexp_check_type(p, "p", NULL)))
return NULL;
SEXP_NEXT(i); q = SEXP_GET(i);
if (!(q && sexp_check_type(q, "q", NULL)))
return NULL;
SEXP_NEXT(i); g = SEXP_GET(i);
if (!(g && sexp_check_type(g, "g", NULL)))
return NULL;
SEXP_NEXT(i); y = SEXP_GET(i);
if (!(y && sexp_check_type(y, "y", NULL)))
return NULL;
SEXP_NEXT(i); x = SEXP_GET(i);
if (!(x && sexp_check_type(x, "x", NULL)))
return NULL;
SEXP_NEXT(i);
if (SEXP_GET(i))
return NULL;
return sexp_l(2, sexp_z("public-key"),
sexp_l(5, sexp_z("dss"), p, q, g, y, -1), -1);
}
/* CLASS:
(class
(name write_key)
(super sexp_handler)
(vars
(status . "int *")
(public_file . "char *")
(private_file . "char *")))
*/
static int do_write_key(struct sexp_handler *h, struct sexp *private)
{
CAST(write_key, closure, h);
struct sexp_iterator *i;
struct sexp *public;
struct sexp *e;
int public_fd;
int private_fd;
if (!sexp_check_type(private, "private-key", &i))
{
werror("lsh_writekey: Not a private key.");
return LSH_FAIL | LSH_DIE;
}
e = SEXP_GET(i);
if (! (e && sexp_check_type(e, "dss", &i)))
{
werror("lsh_writekey: Unknown key type (only dss is supported)\n");
return LSH_FAIL | LSH_DIE;
}
public = dss_private2public(i);
if (!public)
{
werror("lsh_writekey: Invalid dss key\n");
return LSH_FAIL | LSH_DIE;
}
if ((public_fd = open(closure->public_file,
O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0)
{
werror("lsh_writekey: Failed to open %s (errno = %d): %s\n",
closure->public_file, errno, strerror(errno));
return LSH_FAIL | LSH_DIE;
}
if ((private_fd = open(closure->private_file,
O_CREAT | O_EXCL | O_WRONLY, 0600)) < 0)
{
werror("lsh_writekey: Failed to open %s (errno = %d): %s\n",
closure->private_file, errno, strerror(errno));
return LSH_FAIL | LSH_DIE;
}
if (LSH_FAILUREP(A_WRITE(make_blocking_write(public_fd, 0),
sexp_format(public, SEXP_TRANSPORT, 0))))
{
werror("lsh_writekey: Writing to %s failed (errno = %d): %s\n",
closure->public_file, errno, strerror(errno));
return LSH_FAIL | LSH_DIE;
}
if (LSH_FAILUREP(A_WRITE(make_blocking_write(private_fd, 0),
sexp_format(private, SEXP_CANONICAL, 0))))
{
werror("lsh_writekey: Writing to %s failed (errno = %d): %s\n",
closure->private_file, errno, strerror(errno));
return LSH_FAIL | LSH_DIE;
}
*closure->status = EXIT_SUCCESS;
return LSH_OK | LSH_DIE;
}
#define BLOCK_SIZE 2000
static void usage(void)
{
werror("Usage: lsh_writekey [filename]\n");
}
int main(int argc UNUSED, char **argv UNUSED)
{
NEW(io_backend, backend);
NEW(write_key, handler);
int status = 1;
char *public;
char *private;
switch (argc)
{
case 1:
{
char *home = getenv("HOME");
char *buf;
if (!home)
{
werror("lsh_keygen: $HOME not set.\n");
return 1;
}
buf = alloca(strlen(home) + 20);
sprintf(buf, "%s/.lsh", home);
if (mkdir(buf, 0755) < 0)
{
if (errno != EEXIST)
{
werror("lsh_writekey: Creating directory %s failed "
"(errno = %d): %s\n", buf, errno, strerror(errno));
return EXIT_FAILURE;
}
}
else
werror("lsh_writekey: Created directory %s\n", buf);
sprintf(buf, "%s/.lsh/identity", home);
private = buf;
break;
}
case 2:
if (argv[1][0] != '-')
{
private = argv[1];
break;
}
/* Fall through */
default:
usage();
return EXIT_FAILURE;
}
public = alloca(strlen(private) + 5);
sprintf(public, "%s.pub", private);
init_backend(backend);
handler->super.handler = do_write_key;
handler->status = &status;
handler->public_file = public;
handler->private_file = private;
io_read(backend, STDIN_FILENO,
make_read_sexp(&handler->super, BLOCK_SIZE, SEXP_TRANSPORT, 0),
NULL);
io_run(backend);
return status;
}
...@@ -86,7 +86,6 @@ int main(int argc UNUSED, char **argv UNUSED) ...@@ -86,7 +86,6 @@ int main(int argc UNUSED, char **argv UNUSED)
int status = 17; int status = 17;
init_backend(backend); init_backend(backend);
set_error_stream(STDERR_FILENO, 1);
write = io_write(backend, STDOUT_FILENO, BLOCK_SIZE, NULL)->buffer; write = io_write(backend, STDOUT_FILENO, BLOCK_SIZE, NULL)->buffer;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment