~ubuntu-branches/ubuntu/vivid/libssh2/vivid-proposed

« back to all changes in this revision

Viewing changes to src/userauth.c

  • Committer: Bazaar Package Importer
  • Author(s): Mikhail Gusarov
  • Date: 2010-02-28 13:11:14 UTC
  • mto: (1.1.6 upstream) (2.1.8 sid)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20100228131114-g8d2ps9p1u8i80s3
Tags: upstream-1.2.4
ImportĀ upstreamĀ versionĀ 1.2.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
#include <ctype.h>
42
42
#include <stdio.h>
43
43
 
 
44
#include <assert.h>
 
45
 
44
46
/* Needed for struct iovec on some platforms */
45
47
#ifdef HAVE_SYS_UIO_H
46
48
#include <sys/uio.h>
104
106
 
105
107
    if (session->userauth_list_state == libssh2_NB_state_created) {
106
108
        rc = _libssh2_transport_write(session, session->userauth_list_data,
107
 
                                  session->userauth_list_data_len);
 
109
                                      session->userauth_list_data_len);
108
110
        if (rc == PACKET_EAGAIN) {
109
111
            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
110
112
                          "Would block requesting userauth list", 0);
155
157
        memmove(session->userauth_list_data, session->userauth_list_data + 5,
156
158
                methods_len);
157
159
        session->userauth_list_data[methods_len] = '\0';
158
 
        _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s",
 
160
        _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Permitted auth methods: %s",
159
161
                       session->userauth_list_data);
160
162
    }
161
163
 
206
208
    unsigned char *s;
207
209
    static const unsigned char reply_codes[4] =
208
210
        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
209
 
        SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0
210
 
    };
 
211
          SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0
 
212
        };
211
213
    int rc;
212
214
 
213
215
    if (session->userauth_pswd_state == libssh2_NB_state_idle) {
256
258
        memcpy(s, password, password_len);
257
259
        s += password_len;
258
260
 
259
 
        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
261
        _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
260
262
                       "Attempting to login using password authentication");
261
263
 
262
264
        session->userauth_pswd_state = libssh2_NB_state_created;
264
266
 
265
267
    if (session->userauth_pswd_state == libssh2_NB_state_created) {
266
268
        rc = _libssh2_transport_write(session, session->userauth_pswd_data,
267
 
                                  session->userauth_pswd_data_len);
 
269
                                      session->userauth_pswd_data_len);
268
270
        if (rc == PACKET_EAGAIN) {
269
271
            return rc;
270
272
        } else if (rc) {
301
303
            }
302
304
 
303
305
            if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
304
 
                _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
306
                _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
305
307
                               "Password authentication successful");
306
308
                LIBSSH2_FREE(session, session->userauth_pswd_data);
307
309
                session->userauth_pswd_data = NULL;
308
310
                session->state |= LIBSSH2_STATE_AUTHENTICATED;
309
311
                session->userauth_pswd_state = libssh2_NB_state_idle;
310
312
                return 0;
 
313
            } else if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_FAILURE) {
 
314
                _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
 
315
                               "Password authentication failed");
 
316
                LIBSSH2_FREE(session, session->userauth_pswd_data);
 
317
                session->userauth_pswd_data = NULL;
 
318
                session->userauth_pswd_state = libssh2_NB_state_idle;
 
319
                libssh2_error(session,
 
320
                              LIBSSH2_ERROR_AUTHENTICATION_FAILED,
 
321
                              "Authentication failed (username/password)",
 
322
                              0);
 
323
                return -1;
311
324
            }
312
325
 
313
326
            session->userauth_pswd_newpw = NULL;
325
338
            if ((session->userauth_pswd_state == libssh2_NB_state_sent1) ||
326
339
                (session->userauth_pswd_state == libssh2_NB_state_sent2)) {
327
340
                if (session->userauth_pswd_state == libssh2_NB_state_sent1) {
328
 
                    _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
341
                    _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
329
342
                                   "Password change required");
330
343
                    LIBSSH2_FREE(session, session->userauth_pswd_data);
331
344
                    session->userauth_pswd_data = NULL;
398
411
 
399
412
                    if (session->userauth_pswd_state == libssh2_NB_state_sent2) {
400
413
                        rc = _libssh2_transport_write(session,
401
 
                                                  session->userauth_pswd_data,
402
 
                                                  session->
403
 
                                                  userauth_pswd_data_len);
 
414
                                                      session->userauth_pswd_data,
 
415
                                                      session->
 
416
                                                      userauth_pswd_data_len);
404
417
                        if (rc == PACKET_EAGAIN) {
405
418
                            return rc;
406
419
                        } else if (rc) {
469
482
 *
470
483
 * Read a public key from an id_???.pub style file
471
484
 *
472
 
 * Returns an allocated string in *pubkeydata on success.
 
485
 * Returns an allocated string containing the decoded key in *pubkeydata 
 
486
 * on success.
 
487
 * Returns an allocated string containing the key method (e.g. "ssh-dss")
 
488
 * in method on success.
473
489
 */
474
490
static int
475
491
file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
484
500
    size_t pubkey_len = 0;
485
501
    unsigned int tmp_len;
486
502
 
487
 
    _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading public key file: %s",
 
503
    _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s",
488
504
                   pubkeyfile);
489
505
    /* Read Public Key */
490
506
    fd = fopen(pubkeyfile, "r");
542
558
        LIBSSH2_FREE(session, pubkey);
543
559
        return -1;
544
560
    }
545
 
    /* Wasting some bytes here (okay, more than some),
546
 
     * but since it's likely to be freed soon anyway,
547
 
     * we'll just avoid the extra free/alloc and call it a wash */
548
 
    *method = pubkey;
549
 
    *method_len = sp1 - pubkey;
550
561
 
551
562
    sp1++;
552
563
 
553
 
    if ((sp2 = memchr(sp1, ' ', pubkey_len - *method_len)) == NULL) {
 
564
    if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) {
554
565
        /* Assume that the id string is missing, but that it's okay */
555
566
        sp2 = pubkey + pubkey_len;
556
567
    }
562
573
        LIBSSH2_FREE(session, pubkey);
563
574
        return -1;
564
575
    }
 
576
 
 
577
    /* Wasting some bytes here (okay, more than some), but since it's likely
 
578
     * to be freed soon anyway, we'll just avoid the extra free/alloc and call
 
579
     * it a wash */
 
580
    *method = pubkey;
 
581
    *method_len = sp1 - pubkey - 1;
 
582
 
565
583
    *pubkeydata = tmp;
566
584
    *pubkeydata_len = tmp_len;
567
585
 
583
601
    const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail =
584
602
        libssh2_hostkey_methods();
585
603
 
586
 
    _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading private key file: %s",
 
604
    _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading private key file: %s",
587
605
                   privkeyfile);
588
606
    *hostkey_method = NULL;
589
607
    *hostkey_abstract = NULL;
613
631
    return 0;
614
632
}
615
633
 
 
634
struct privkey_file {
 
635
    const char *filename;
 
636
    const char *passphrase;
 
637
};
 
638
 
 
639
static int
 
640
sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
 
641
              const unsigned char *data, size_t data_len, void **abstract)
 
642
{
 
643
    struct privkey_file *privkey_file = (struct privkey_file *) (*abstract);
 
644
    const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
 
645
    void *hostkey_abstract;
 
646
    struct iovec datavec;
 
647
 
 
648
    if (file_read_privatekey(session, &privkeyobj, &hostkey_abstract,
 
649
                             session->userauth_pblc_method,
 
650
                             session->userauth_pblc_method_len,
 
651
                             privkey_file->filename,
 
652
                             privkey_file->passphrase)) {
 
653
        return -1;
 
654
    }
 
655
 
 
656
    datavec.iov_base = (unsigned char *)data;
 
657
    datavec.iov_len = data_len;
 
658
 
 
659
    if (privkeyobj->signv(session, sig, (unsigned long *)sig_len, 1, &datavec,
 
660
                          &hostkey_abstract)) {
 
661
        if (privkeyobj->dtor) {
 
662
            privkeyobj->dtor(session, abstract);
 
663
        }
 
664
        return -1;
 
665
    }
 
666
 
 
667
    if (privkeyobj->dtor) {
 
668
        privkeyobj->dtor(session, &hostkey_abstract);
 
669
    }
 
670
    return 0;
 
671
}
 
672
 
616
673
 
617
674
 
618
675
/* userauth_hostbased_fromfile
627
684
                            const char *local_username,
628
685
                            unsigned int local_username_len)
629
686
{
630
 
    static const unsigned char reply_codes[3] =
631
 
        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
632
687
    int rc;
633
688
 
634
689
    if (session->userauth_host_state == libssh2_NB_state_idle) {
797
852
        session->userauth_host_s += sig_len;
798
853
        LIBSSH2_FREE(session, sig);
799
854
 
800
 
        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
855
        _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
801
856
                       "Attempting hostbased authentication");
802
857
 
803
858
        session->userauth_host_state = libssh2_NB_state_created;
824
879
    }
825
880
 
826
881
    if (session->userauth_host_state == libssh2_NB_state_sent) {
 
882
        static const unsigned char reply_codes[3] =
 
883
            { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
827
884
        unsigned long data_len;
828
885
        rc = _libssh2_packet_requirev(session, reply_codes,
829
886
                                      &session->userauth_host_data,
839
896
            return -1;
840
897
 
841
898
        if (session->userauth_host_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
842
 
            _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
899
            _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
843
900
                           "Hostbased authentication successful");
844
901
            /* We are us and we've proved it. */
845
902
            LIBSSH2_FREE(session, session->userauth_host_data);
885
942
 
886
943
 
887
944
 
888
 
/*
889
 
 * userauth_publickey_fromfile
890
 
 * Authenticate using a keypair found in the named files
891
 
 */
892
945
static int
893
 
userauth_publickey_fromfile(LIBSSH2_SESSION *session,
894
 
                            const char *username,
895
 
                            unsigned int username_len,
896
 
                            const char *publickey,
897
 
                            const char *privatekey,
898
 
                            const char *passphrase)
 
946
userauth_publickey(LIBSSH2_SESSION *session,
 
947
                   const char *username,
 
948
                   unsigned int username_len,
 
949
                   const unsigned char *pubkeydata,
 
950
                   unsigned long pubkeydata_len,
 
951
                   LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)),
 
952
                   void *abstract)
899
953
{
900
 
    unsigned long pubkeydata_len = 0;
901
954
    unsigned char reply_codes[4] =
902
955
        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
903
 
        SSH_MSG_USERAUTH_PK_OK, 0
904
 
    };
 
956
          SSH_MSG_USERAUTH_PK_OK, 0
 
957
        };
905
958
    int rc;
906
959
 
907
960
    if (session->userauth_pblc_state == libssh2_NB_state_idle) {
908
 
        unsigned char *pubkeydata;
909
 
 
910
961
        /* Zero the whole thing out */
911
962
        memset(&session->userauth_pblc_packet_requirev_state, 0,
912
963
               sizeof(session->userauth_pblc_packet_requirev_state));
913
964
 
914
 
        if (file_read_publickey(session, &session->userauth_pblc_method,
915
 
                                &session->userauth_pblc_method_len,
916
 
                                &pubkeydata, &pubkeydata_len,publickey)) {
917
 
            return -1;
 
965
        /*
 
966
         * As an optimisation, userauth_publickey_fromfile reuses a 
 
967
         * previously allocated copy of the method name to avoid an extra
 
968
         * allocation/free.
 
969
         * For other uses, we allocate and populate it here.
 
970
         */
 
971
        if (!session->userauth_pblc_method) {
 
972
            session->userauth_pblc_method_len = _libssh2_ntohu32(pubkeydata);
 
973
            session->userauth_pblc_method =
 
974
                LIBSSH2_ALLOC(session, session->userauth_pblc_method_len);
 
975
            if (!session->userauth_pblc_method) {
 
976
                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
 
977
                              "Unable to allocate memory for public key "
 
978
                              "data", 0);
 
979
                return -1;
 
980
            }
 
981
            memcpy(session->userauth_pblc_method, pubkeydata + 4,
 
982
                   session->userauth_pblc_method_len);
918
983
        }
 
984
        assert( /* preallocated method len should match what we expect */
 
985
            session->userauth_pblc_method_len == _libssh2_ntohu32(pubkeydata));
919
986
 
920
987
        /*
921
988
         * 45 = packet_type(1) + username_len(4) + servicename_len(4) +
940
1007
        if (!session->userauth_pblc_packet) {
941
1008
            LIBSSH2_FREE(session, session->userauth_pblc_method);
942
1009
            session->userauth_pblc_method = NULL;
943
 
            LIBSSH2_FREE(session, pubkeydata);
944
1010
            return -1;
945
1011
        }
946
1012
 
965
1031
        *(session->userauth_pblc_s++) = 0;
966
1032
 
967
1033
        _libssh2_htonu32(session->userauth_pblc_s,
968
 
                        session->userauth_pblc_method_len);
 
1034
                         session->userauth_pblc_method_len);
969
1035
        session->userauth_pblc_s += 4;
970
1036
        memcpy(session->userauth_pblc_s, session->userauth_pblc_method,
971
1037
               session->userauth_pblc_method_len);
975
1041
        session->userauth_pblc_s += 4;
976
1042
        memcpy(session->userauth_pblc_s, pubkeydata, pubkeydata_len);
977
1043
        session->userauth_pblc_s += pubkeydata_len;
978
 
        LIBSSH2_FREE(session, pubkeydata);
979
1044
 
980
 
        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
1045
        _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
981
1046
                       "Attempting publickey authentication");
982
1047
 
983
1048
        session->userauth_pblc_state = libssh2_NB_state_created;
985
1050
 
986
1051
    if (session->userauth_pblc_state == libssh2_NB_state_created) {
987
1052
        rc = _libssh2_transport_write(session, session->userauth_pblc_packet,
988
 
                                  session->userauth_pblc_packet_len);
 
1053
                                      session->userauth_pblc_packet_len);
989
1054
        if (rc == PACKET_EAGAIN) {
990
1055
            return rc;
991
1056
        } else if (rc) {
1003
1068
    }
1004
1069
 
1005
1070
    if (session->userauth_pblc_state == libssh2_NB_state_sent) {
1006
 
        const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
1007
 
        void *abstract;
1008
 
        unsigned char buf[5];
1009
 
        struct iovec datavec[4];
1010
 
        unsigned char *sig;
1011
 
        unsigned long sig_len;
1012
 
 
1013
1071
        rc = _libssh2_packet_requirev(session, reply_codes,
1014
1072
                                      &session->userauth_pblc_data,
1015
1073
                                      &session->userauth_pblc_data_len, 0,
1028
1086
        }
1029
1087
 
1030
1088
        if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
1031
 
            _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
1089
            _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
1032
1090
                           "Pubkey authentication prematurely successful");
1033
1091
            /*
1034
1092
             * God help any SSH server that allows an UNVERIFIED
1053
1111
            session->userauth_pblc_packet = NULL;
1054
1112
            LIBSSH2_FREE(session, session->userauth_pblc_method);
1055
1113
            session->userauth_pblc_method = NULL;
1056
 
            libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED,
 
1114
            libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED,
1057
1115
                          "Username/PublicKey combination invalid", 0);
1058
1116
            session->userauth_pblc_state = libssh2_NB_state_idle;
1059
1117
            return -1;
1063
1121
        LIBSSH2_FREE(session, session->userauth_pblc_data);
1064
1122
        session->userauth_pblc_data = NULL;
1065
1123
 
1066
 
        if (file_read_privatekey(session, &privkeyobj, &abstract,
1067
 
                                 session->userauth_pblc_method,
1068
 
                                 session->userauth_pblc_method_len,
1069
 
                                 privatekey, passphrase)) {
1070
 
            LIBSSH2_FREE(session, session->userauth_pblc_method);
1071
 
            session->userauth_pblc_method = NULL;
1072
 
            LIBSSH2_FREE(session, session->userauth_pblc_packet);
1073
 
            session->userauth_pblc_packet = NULL;
1074
 
            session->userauth_pblc_state = libssh2_NB_state_idle;
1075
 
            return -1;
1076
 
        }
1077
 
 
1078
1124
        *session->userauth_pblc_b = 0x01;
1079
 
 
1080
 
        _libssh2_htonu32(buf, session->session_id_len);
1081
 
        datavec[0].iov_base = buf;
1082
 
        datavec[0].iov_len = 4;
1083
 
        datavec[1].iov_base = session->session_id;
1084
 
        datavec[1].iov_len = session->session_id_len;
1085
 
        datavec[2].iov_base = session->userauth_pblc_packet;
1086
 
        datavec[2].iov_len = session->userauth_pblc_packet_len;
1087
 
 
1088
 
        if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) {
 
1125
        session->userauth_pblc_state = libssh2_NB_state_sent1;
 
1126
    }
 
1127
 
 
1128
    if (session->userauth_pblc_state == libssh2_NB_state_sent1) {
 
1129
        unsigned char *buf, *s;
 
1130
        unsigned char *sig;
 
1131
        size_t sig_len;
 
1132
 
 
1133
        s = buf = LIBSSH2_ALLOC(session, 4 + session->session_id_len
 
1134
                                + session->userauth_pblc_packet_len);
 
1135
        if (!buf) {
 
1136
            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
 
1137
                          "Unable to allocate memory for userauth-publickey "
 
1138
                          "signed data", 0);
 
1139
            return -1;
 
1140
        }
 
1141
 
 
1142
        _libssh2_htonu32(s, session->session_id_len);
 
1143
        s += 4;
 
1144
        memcpy (s, session->session_id, session->session_id_len);
 
1145
        s += session->session_id_len;
 
1146
        memcpy (s, session->userauth_pblc_packet,
 
1147
                session->userauth_pblc_packet_len);
 
1148
        s += session->userauth_pblc_packet_len;
 
1149
 
 
1150
        rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract);
 
1151
        LIBSSH2_FREE(session, buf);
 
1152
        if (rc == PACKET_EAGAIN) {
 
1153
            return rc;
 
1154
        } else if (rc) {
1089
1155
            LIBSSH2_FREE(session, session->userauth_pblc_method);
1090
1156
            session->userauth_pblc_method = NULL;
1091
1157
            LIBSSH2_FREE(session, session->userauth_pblc_packet);
1092
1158
            session->userauth_pblc_packet = NULL;
1093
 
            if (privkeyobj->dtor) {
1094
 
                privkeyobj->dtor(session, &abstract);
1095
 
            }
1096
1159
            session->userauth_pblc_state = libssh2_NB_state_idle;
1097
1160
            return -1;
1098
1161
        }
1099
1162
 
1100
 
        if (privkeyobj->dtor) {
1101
 
            privkeyobj->dtor(session, &abstract);
1102
 
        }
1103
 
 
1104
1163
        /*
1105
1164
         * If this function was restarted, pubkeydata_len might still be 0
1106
1165
         * which will cause an unnecessary but harmless realloc here.
1152
1211
        session->userauth_pblc_s += sig_len;
1153
1212
        LIBSSH2_FREE(session, sig);
1154
1213
 
1155
 
        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
1214
        _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
1156
1215
                       "Attempting publickey authentication -- phase 2");
1157
1216
 
1158
 
        session->userauth_pblc_state = libssh2_NB_state_sent1;
 
1217
        session->userauth_pblc_state = libssh2_NB_state_sent2;
1159
1218
    }
1160
1219
 
1161
 
    if (session->userauth_pblc_state == libssh2_NB_state_sent1) {
 
1220
    if (session->userauth_pblc_state == libssh2_NB_state_sent2) {
1162
1221
        rc = _libssh2_transport_write(session, session->userauth_pblc_packet,
1163
1222
                                      session->userauth_pblc_s -
1164
1223
                                      session->userauth_pblc_packet);
1175
1234
        LIBSSH2_FREE(session, session->userauth_pblc_packet);
1176
1235
        session->userauth_pblc_packet = NULL;
1177
1236
 
1178
 
        session->userauth_pblc_state = libssh2_NB_state_sent2;
 
1237
        session->userauth_pblc_state = libssh2_NB_state_sent3;
1179
1238
    }
1180
1239
 
1181
1240
    /* PK_OK is no longer valid */
1193
1252
    }
1194
1253
 
1195
1254
    if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
1196
 
        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
1255
        _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
1197
1256
                       "Publickey authentication successful");
1198
1257
        /* We are us and we've proved it. */
1199
1258
        LIBSSH2_FREE(session, session->userauth_pblc_data);
1214
1273
    return -1;
1215
1274
}
1216
1275
 
 
1276
/*
 
1277
 * userauth_publickey_fromfile
 
1278
 * Authenticate using a keypair found in the named files
 
1279
 */
 
1280
static int
 
1281
userauth_publickey_fromfile(LIBSSH2_SESSION *session,
 
1282
                            const char *username,
 
1283
                            unsigned int username_len,
 
1284
                            const char *publickey,
 
1285
                            const char *privatekey,
 
1286
                            const char *passphrase)
 
1287
{
 
1288
    unsigned char *pubkeydata = NULL;
 
1289
    unsigned long pubkeydata_len = 0;
 
1290
    struct privkey_file privkey_file;
 
1291
    void *abstract = &privkey_file;
 
1292
    int rc;
 
1293
 
 
1294
    privkey_file.filename = privatekey;
 
1295
    privkey_file.passphrase = passphrase;
 
1296
 
 
1297
    if (session->userauth_pblc_state == libssh2_NB_state_idle) {
 
1298
        if (file_read_publickey(session, &session->userauth_pblc_method,
 
1299
                                &session->userauth_pblc_method_len,
 
1300
                                &pubkeydata, &pubkeydata_len, publickey)) {
 
1301
            return -1;
 
1302
        }
 
1303
    }
 
1304
 
 
1305
    rc = userauth_publickey(session, username, username_len,
 
1306
                            pubkeydata, pubkeydata_len,
 
1307
                            sign_fromfile, &abstract);
 
1308
    if(pubkeydata)
 
1309
        LIBSSH2_FREE(session, pubkeydata);
 
1310
 
 
1311
    return rc;
 
1312
}
 
1313
 
1217
1314
/* libssh2_userauth_publickey_fromfile_ex
1218
1315
 * Authenticate using a keypair found in the named files
1219
1316
 */
1233
1330
    return rc;
1234
1331
}
1235
1332
 
 
1333
/* libssh2_userauth_publickey_ex
 
1334
 * Authenticate using an external callback function
 
1335
 */
 
1336
LIBSSH2_API int
 
1337
libssh2_userauth_publickey(LIBSSH2_SESSION *session,
 
1338
                           const char *user,
 
1339
                           const unsigned char *pubkeydata,
 
1340
                           size_t pubkeydata_len,
 
1341
                           LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)),
 
1342
                           void **abstract)
 
1343
{
 
1344
    int rc;
 
1345
    BLOCK_ADJUST(rc, session,
 
1346
                 userauth_publickey(session, user, strlen(user),
 
1347
                                    pubkeydata, pubkeydata_len,
 
1348
                                    sign_callback, abstract));
 
1349
    return rc;
 
1350
}
 
1351
 
1236
1352
 
1237
1353
 
1238
1354
/*
1249
1365
    unsigned char *s;
1250
1366
    int rc;
1251
1367
 
1252
 
    static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS,
 
1368
    static const unsigned char reply_codes[4] = {
 
1369
        SSH_MSG_USERAUTH_SUCCESS,
1253
1370
        SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0
1254
1371
    };
1255
1372
    unsigned int language_tag_len;
1316
1433
        _libssh2_htonu32(s, 0);
1317
1434
        s += 4;
1318
1435
 
1319
 
        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
1436
        _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
1320
1437
                       "Attempting keyboard-interactive authentication");
1321
1438
 
1322
1439
        session->userauth_kybd_state = libssh2_NB_state_created;
1324
1441
 
1325
1442
    if (session->userauth_kybd_state == libssh2_NB_state_created) {
1326
1443
        rc = _libssh2_transport_write(session, session->userauth_kybd_data,
1327
 
                                  session->userauth_kybd_packet_len);
 
1444
                                      session->userauth_kybd_packet_len);
1328
1445
        if (rc == PACKET_EAGAIN) {
1329
1446
            return rc;
1330
1447
        } else if (rc) {
1357
1474
            }
1358
1475
 
1359
1476
            if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
1360
 
                _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
1477
                _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
1361
1478
                               "Keyboard-interactive authentication successful");
1362
1479
                LIBSSH2_FREE(session, session->userauth_kybd_data);
1363
1480
                session->userauth_kybd_data = NULL;
1367
1484
            }
1368
1485
 
1369
1486
            if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_FAILURE) {
 
1487
                _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
 
1488
                               "Keyboard-interactive authentication failed");
1370
1489
                LIBSSH2_FREE(session, session->userauth_kybd_data);
1371
1490
                session->userauth_kybd_data = NULL;
1372
1491
                session->userauth_kybd_state = libssh2_NB_state_idle;
 
1492
                libssh2_error(session,
 
1493
                              LIBSSH2_ERROR_AUTHENTICATION_FAILED,
 
1494
                              "Authentication failed (keyboard-interactive)",
 
1495
                              0);
1373
1496
                return -1;
1374
1497
            }
1375
1498
 
1482
1605
                              session->userauth_kybd_responses,
1483
1606
                              &session->abstract);
1484
1607
 
1485
 
            _libssh2_debug(session, LIBSSH2_DBG_AUTH,
 
1608
            _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
1486
1609
                           "Keyboard-interactive response callback function"
1487
1610
                           " invoked");
1488
1611
 
1525
1648
 
1526
1649
        if (session->userauth_kybd_state == libssh2_NB_state_sent1) {
1527
1650
            rc = _libssh2_transport_write(session, session->userauth_kybd_data,
1528
 
                                       session->userauth_kybd_packet_len);
 
1651
                                          session->userauth_kybd_packet_len);
1529
1652
            if (rc == PACKET_EAGAIN) {
1530
1653
                return rc;
1531
1654
            }