1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#! /usr/bin/perl
# **** License ****
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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.
#
# This code was originally developed by Vyatta, Inc.
# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc.
# All Rights Reserved.
#
# Author: Stephen Hemminger
# Date: 2009
#
# **** End License ****
use lib "/opt/vyatta/share/perl5/";
use strict;
use warnings;
use Vyatta::Config;
sub usage {
print "Usage: $0 user filename|url\n";
exit 1;
}
sub check_http {
my ($url) = @_;
#
# error codes are send back in html, so 1st try a header
# and look for "HTTP/1.1 200 OK"
#
my $rc = `curl -s -q -I $url 2>&1`;
if ( $rc =~ /HTTP\/\d+\.?\d\s+(\d+)\s+(.*)$/mi ) {
my $rc_code = $1;
my $rc_string = $2;
die "http error: [$rc_code] $rc_string\n"
unless ( $rc_code == 200 );
} else {
die "Error: $rc\n";
}
}
sub geturl {
my ($proto, $url) = @_;
if ($proto eq 'http') {
check_http($url)
}
my $cmd = "curl -#";
# Handle user@host syntax which curl doesn't do
if ($proto eq 'scp') {
if ($url =~ m#scp://(\w+)@(.*)# ) {
$cmd .= " -u $1";
$url = "scp://$2";
}
}
$cmd .= " $url";
open (my $curl, "$cmd |" )
or die "$cmd command failed: $!\n";
return $curl;
}
usage unless ($#ARGV == 1);
my $user = $ARGV[0];
my $source = $ARGV[1];
my $sbindir = $ENV{vyatta_sbindir};
my $config = new Vyatta::Config;
$config->setLevel("system login user");
die "User $user does not exist in current configuration\n"
unless $config->exists($user);
# If it has protocol:// then use curl to copy
my $in;
if ( $source =~ m#(^[^/]\w+)://# ) {
$in = geturl ($1, $source);
} else {
open(my $in, '<', $source)
or die "Cannot open file $source: $!\n";
}
while (<$in>) {
chomp;
# public key (format 2) consist of:
# options, keytype, base64-encoded key, comment.
# The options field is optional (but not supported).
my ($keytype, $keycode, $comment) = split / /;
die "Not a valid key file format (see man sshd)"
unless defined($keytype) && defined($keycode) && defined($comment);
die "$keytype: not a known ssh public format\n"
unless ($keytype =~ /ssh-rsa|ssh-dsa/);
my $cmd = "set system login user $user authentication public-keys $comment";
system ("$sbindir/my_$cmd" . " key $keycode");
die "\"$cmd\" key failed\n"
if ($? >> 8);
system ("$sbindir/my_$cmd" . " type $keytype");
die "\"$cmd\" type failed\n"
if ($? >> 8);
}
close $in;
system("$sbindir/my_commit");
if ( $? >> 8 ) {
print "Load failed (commit failed)\n";
exit 1;
}
print "Done\n";
exit 0;
|