FeddDownload: addpubkey.patch

File addpubkey.patch, 7.0 KB (added by faber, 15 years ago)
  • addpubkey

    RCS file: /usr/DETER/cvsroot/testbed/account/addpubkey.in,v
    retrieving revision 1.1.1.3
    diff -u -r1.1.1.3 addpubkey.in
     
    4343    print " -w      Generate new authkeys (protocol 1 and 2) file for user\n";
    4444    print " -i      Initialize mode; generate initial key for user\n";
    4545    print " -r      Force a regenerate of initial key for user\n";
     46    print " -R      Remove key from user\n";
     47    print " -C      Confirm key is assigned to user\n";
    4648    exit(-1);
    4749}
    48 my $optlist   = "dkniwfu:rX:";
     50my $optlist   = "dkniwfu:rX:RC";
    4951my $iskey     = 0;
    5052my $verify    = 0;
    5153my $initmode  = 0;
     
    7880my $user_dbid;
    7981my $user_uid;
    8082my $debug = 0;
     83my $delete = 0;
     84my $confirm = 0;
    8185
    8286#
    8387# Testbed Support libraries
     
    9094#
    9195# Function prototypes
    9296#
    93 sub ParseKey($);
     97sub CheckKey($);
     98sub AddKey($);
    9499sub InitUser();
    95100sub GenerateKeyFile();
    96101sub ParseXmlArgs($$$$$$);
     
    169174if (defined($options{"u"})) {
    170175    $user = $options{"u"};
    171176}
     177if (defined($options{"R"})) {
     178    $delete = 1;
     179}
     180if (defined($options{"C"})) {
     181    $confirm = 1;
     182}
    172183if (defined($options{"X"})) {
    173184    $xmlfile = $options{"X"};
    174185
     
    190201    $ARGV[0] = $xmlargs{"keyfile"};
    191202}
    192203
     204if ( $delete && $confirm ) {
     205    usage();
     206}
     207
    193208if ($verify && $genmode) {
    194209    usage();
    195210}
     
    313328    AuditStart(0);
    314329}
    315330
     331# The control flow is the same for add and delete.  Pick the action and follow
     332# that flow. 
     333my $action = undef;
     334
     335if ($delete ) { $action = \&DeleteKey; }
     336elsif ($confirm) { $action = \&ConfirmKey; }
     337else { $action = \&AddKey; }
     338
    316339#
    317340# Grab the first line of the file. Parse it to see if its in the
    318341# format we like (openssh), either protocol 1 or 2.
    319342#
    320 if (ParseKey($keyline)) {
     343if (&$action($keyline)) {
    321344    exit 0;
    322345}
    323346# If the key was entered on the command line, then nothing more to do.
     
    333356          "    Could not start ssh-keygen\n");
    334357}
    335358$keyline = <KEYGEN>;
    336 if (close(KEYGEN) && ParseKey($keyline)) {
     359if (close(KEYGEN) && &$action($keyline)) {
    337360    exit 0;
    338361}
    339362exit 1;
    340363
    341 sub ParseKey($) {
     364# Make sure the key is properly formatted.  If so, return the key in a
     365# canonical format, the comment, and type as a list, otherwise return undef.
     366sub CheckKey($) {
    342367    my ($keyline) = @_;
     368    my $comment;
     369    my $type;
    343370
    344371    # Remove trailing newlines which screws the patterns below.
    345372    # First convert dos newlines since many people upload from windoze.
    346373    $keyline =~ s/\r/\n/g;
    347374    $keyline =~ s/\n//g;
    348375
    349     # Enforce a reasonable length on the key.
    350     if (length($keyline) > 4096) {
    351         print "Key is too long!\n";
    352         print "Key: $keyline\n";
    353         return 0;
    354     }
    355    
    356376    if ($keyline =~ /^(\d*\s\d*\s[0-9a-zA-Z]*) ([-\w\@\.\ ]*)\s*$/) {
    357377        # Protocol 1
    358378        $type    = "ssh-rsa1";
     
    378398    }
    379399
    380400    if (!defined($key)) {
     401        return undef;
     402    }
     403
     404    #
     405    # Make up a comment field for the DB.
     406    #
     407    if (!defined($comment)) {
     408        $comment = "$type-${user_email}";
     409    }
     410    $key = "$key $comment";
     411    return ($key, $comment, $type);
     412}
     413
     414
     415sub ConfirmKey($) {
     416    my ($keyline) = @_;
     417
     418    # Enforce a reasonable length on the key.
     419    if (length($keyline) > 4096) {
     420        print "Key is too long!\n";
     421        print "Key: $keyline\n";
     422        return 0;
     423    }
     424
     425    my ($key, $comment, $type)  = CheckKey($keyline);
     426
     427    if (!$key) {
    381428        print "Key cannot be parsed!\n";
    382429        print "Key: $keyline\n";
    383430        return 0;
    384431    }
     432   
     433    # Do not enter into DB if in verify mode.
     434    if ($verify && $key ) {
     435        print "Key was good: $type\n";
     436        return 1;
     437    }
     438
     439    my $sth = DBQueryFatal("select uid from user_pubkeys " .
     440        "where uid='$user_uid' and pubkey='$key'");
     441
     442    my $chunked = "";
     443
     444    while (length($key)) {
     445        $chunked .= substr($key, 0, 65, "");
     446        if (length($key)) {
     447            $chunked .= "\n";
     448        }
     449    }
     450    if ($sth->rows() == 1) {
     451        print "SSH Public Key for '$user' confirmed:\n";
     452        print "$chunked\n";
     453        return 1;
     454    }
     455    else {
     456        print "SSH Public Key for '$user' not present:\n";
     457        print "$chunked\n";
     458        return 0;
     459    }
     460}
     461
     462
     463sub AddKey($) {
     464    my ($keyline) = @_;
     465
     466    # Enforce a reasonable length on the key.
     467    if (length($keyline) > 4096) {
     468        print "Key is too long!\n";
     469        print "Key: $keyline\n";
     470        return 0;
     471    }
     472
     473    my ($key, $comment, $type)  = CheckKey($keyline);
    385474
     475    if (!$key) {
     476        print "Key cannot be parsed!\n";
     477        print "Key: $keyline\n";
     478        return 0;
     479    }
     480   
    386481    # Do not enter into DB if in verify mode.
    387     if ($verify) {
     482    if ($verify && $key ) {
    388483        print "Key was good: $type\n";
    389484        return 1;
    390485    }
    391486
    392     #
    393     # Make up a comment field for the DB.
    394     #
    395     if (!defined($comment)) {
    396         $comment = "$type-${user_email}";
     487
     488    # If the key is already present, just report success.
     489    if (!ConfirmKey($keyline)) {
     490        DBQueryFatal("replace into user_pubkeys ".
     491                     "values ('$user_uid', '$user_dbid', ".
     492                     "        0, '$key', now(), '$comment')");
     493
     494        #
     495        # Mark user record as modified so nodes are updated.
     496        #
     497        TBNodeUpdateAccountsByUID($user_uid);
     498
     499        my $chunked = "";
     500
     501        while (length($key)) {
     502            $chunked .= substr($key, 0, 65, "");
     503            if (length($key)) {
     504                $chunked .= "\n";
     505            }
     506        }
     507        print "SSH Public Key for '$user' added:\n";
     508        print "$chunked\n";
     509       
     510        # Generate new auth keys file.
     511        if ($genmode) {
     512            GenerateKeyFile();
     513        }
     514
     515        if (! $noemail) {
     516            SENDMAIL("$user_name <$user_email>",
     517                     "SSH Public Key for '$user_uid' Added",
     518                     "SSH Public Key for '$user_uid' added:\n".
     519                     "\n".
     520                     "$chunked\n",
     521                     "$TBOPS");
     522        }
     523    }
     524    return 1;
     525}
     526
     527sub DeleteKey($) {
     528    my ($keyline) = @_;
     529
     530    # Enforce a reasonable length on the key.
     531    if (length($keyline) > 4096) {
     532        print "Key is too long!\n";
     533        print "Key: $keyline\n";
     534        return 0;
     535    }
     536
     537    my ($key, $comment, $type)  = CheckKey($keyline);
     538
     539    if (!$key) {
     540        print "Key cannot be parsed!\n";
     541        print "Key: $keyline\n";
     542        return 0;
     543    }
     544   
     545    # Do not enter into DB if in verify mode.
     546    if ($verify && $key ) {
     547        print "Key was good: $type\n";
     548        return 1;
    397549    }
    398     $key = "$key $comment";
    399550
    400     DBQueryFatal("replace into user_pubkeys ".
    401                  "values ('$user_uid', '$user_dbid', ".
    402                  "        0, '$key', now(), '$comment')");
     551    DBQueryFatal("delete from user_pubkeys ".
     552                 "where uid='$user_uid' and uid_idx='$user_dbid' and ".
     553                 "pubkey='$key'");
    403554
    404555    #
    405556    # Mark user record as modified so nodes are updated.
     
    414565            $chunked .= "\n";
    415566        }
    416567    }
    417     print "SSH Public Key for '$user' added:\n";
     568    print "SSH Public Key for '$user' deleted:\n";
    418569    print "$chunked\n";
    419570   
    420571    # Generate new auth keys file.
     
    424575
    425576    if (! $noemail) {
    426577        SENDMAIL("$user_name <$user_email>",
    427                  "SSH Public Key for '$user_uid' Added",
    428                  "SSH Public Key for '$user_uid' added:\n".
     578                 "SSH Public Key for '$user_uid' removed",
     579                 "SSH Public Key for '$user_uid' removed:\n".
    429580                 "\n".
    430581                 "$chunked\n",
    431582                 "$TBOPS");