1 /*
2  * This file is part of the SSH Library
3  *
4  * Copyright (c) 2010 by Aris Adamantiadis
5  *
6  * The SSH Library is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or (at your
9  * option) any later version.
10  *
11  * The SSH Library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  * License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with the SSH Library; see the file COPYING.  If not, write to
18  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19  * MA 02111-1307, USA.
20  */
21 
22 /** functions in that file are wrappers to the newly named functions. All
23  * of them are depreciated, but these wrapper will avoid breaking backward
24  * compatibility
25  */
26 
27 #include "config.h"
28 
29 #include <errno.h>
30 #include <stdio.h>
31 
32 #include <libssh/priv.h>
33 #include <libssh/session.h>
34 #include <libssh/server.h>
35 #include <libssh/buffer.h>
36 #include <libssh/pki.h>
37 #include "libssh/pki_priv.h"
38 #include <libssh/misc.h>
39 #include <libssh/keys.h>
40 #include "libssh/options.h"
41 
42 /* AUTH FUNCTIONS */
ssh_auth_list(ssh_session session)43 int ssh_auth_list(ssh_session session) {
44   return ssh_userauth_list(session, NULL);
45 }
46 
ssh_userauth_offer_pubkey(ssh_session session,const char * username,int type,ssh_string publickey)47 int ssh_userauth_offer_pubkey(ssh_session session, const char *username,
48     int type, ssh_string publickey)
49 {
50     ssh_key key;
51     int rc;
52 
53     (void) type; /* unused */
54 
55     rc = ssh_pki_import_pubkey_blob(publickey, &key);
56     if (rc < 0) {
57         ssh_set_error(session, SSH_FATAL, "Failed to convert public key");
58         return SSH_AUTH_ERROR;
59     }
60 
61     rc = ssh_userauth_try_publickey(session, username, key);
62     ssh_key_free(key);
63 
64     return rc;
65 }
66 
ssh_userauth_pubkey(ssh_session session,const char * username,ssh_string publickey,ssh_private_key privatekey)67 int ssh_userauth_pubkey(ssh_session session,
68                         const char *username,
69                         ssh_string publickey,
70                         ssh_private_key privatekey)
71 {
72     ssh_key key;
73     int rc;
74 
75     (void) publickey; /* unused */
76 
77     key = ssh_key_new();
78     if (key == NULL) {
79         return SSH_AUTH_ERROR;
80     }
81 
82     key->type = privatekey->type;
83     key->type_c = ssh_key_type_to_char(key->type);
84     key->flags = SSH_KEY_FLAG_PRIVATE|SSH_KEY_FLAG_PUBLIC;
85     key->dsa = privatekey->dsa_priv;
86     key->rsa = privatekey->rsa_priv;
87 
88     rc = ssh_userauth_publickey(session, username, key);
89     key->dsa = NULL;
90     key->rsa = NULL;
91     ssh_key_free(key);
92 
93     return rc;
94 }
95 
ssh_userauth_autopubkey(ssh_session session,const char * passphrase)96 int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
97     return ssh_userauth_publickey_auto(session, NULL, passphrase);
98 }
99 
ssh_userauth_privatekey_file(ssh_session session,const char * username,const char * filename,const char * passphrase)100 int ssh_userauth_privatekey_file(ssh_session session,
101                                  const char *username,
102                                  const char *filename,
103                                  const char *passphrase) {
104   char *pubkeyfile = NULL;
105   ssh_string pubkey = NULL;
106   ssh_private_key privkey = NULL;
107   int type = 0;
108   int rc = SSH_AUTH_ERROR;
109 
110   enter_function();
111 
112   pubkeyfile = malloc(strlen(filename) + 1 + 4);
113   if (pubkeyfile == NULL) {
114     ssh_set_error_oom(session);
115     leave_function();
116     return SSH_AUTH_ERROR;
117   }
118   sprintf(pubkeyfile, "%s.pub", filename);
119 
120   pubkey = publickey_from_file(session, pubkeyfile, &type);
121   if (pubkey == NULL) {
122     ssh_log(session, SSH_LOG_RARE, "Public key file %s not found. Trying to generate it.", pubkeyfile);
123     /* auto-detect the key type with type=0 */
124     privkey = privatekey_from_file(session, filename, 0, passphrase);
125   } else {
126     ssh_log(session, SSH_LOG_RARE, "Public key file %s loaded.", pubkeyfile);
127     privkey = privatekey_from_file(session, filename, type, passphrase);
128   }
129   if (privkey == NULL) {
130     goto error;
131   }
132   /* ssh_userauth_pubkey is responsible for taking care of null-pubkey */
133   rc = ssh_userauth_pubkey(session, username, pubkey, privkey);
134   privatekey_free(privkey);
135 
136 error:
137   SAFE_FREE(pubkeyfile);
138   ssh_string_free(pubkey);
139 
140   leave_function();
141   return rc;
142 }
143 
144 /* BUFFER FUNCTIONS */
145 
buffer_free(ssh_buffer buffer)146 void buffer_free(ssh_buffer buffer){
147   ssh_buffer_free(buffer);
148 }
buffer_get(ssh_buffer buffer)149 void *buffer_get(ssh_buffer buffer){
150   return ssh_buffer_get_begin(buffer);
151 }
buffer_get_len(ssh_buffer buffer)152 uint32_t buffer_get_len(ssh_buffer buffer){
153   return ssh_buffer_get_len(buffer);
154 }
buffer_new(void)155 ssh_buffer buffer_new(void){
156   return ssh_buffer_new();
157 }
158 
channel_accept_x11(ssh_channel channel,int timeout_ms)159 ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms){
160   return ssh_channel_accept_x11(channel, timeout_ms);
161 }
162 
channel_change_pty_size(ssh_channel channel,int cols,int rows)163 int channel_change_pty_size(ssh_channel channel,int cols,int rows){
164   return ssh_channel_change_pty_size(channel,cols,rows);
165 }
166 
channel_forward_accept(ssh_session session,int timeout_ms)167 ssh_channel channel_forward_accept(ssh_session session, int timeout_ms){
168   return ssh_forward_accept(session,timeout_ms);
169 }
170 
channel_close(ssh_channel channel)171 int channel_close(ssh_channel channel){
172   return ssh_channel_close(channel);
173 }
174 
channel_forward_cancel(ssh_session session,const char * address,int port)175 int channel_forward_cancel(ssh_session session, const char *address, int port){
176   return ssh_forward_cancel(session, address, port);
177 }
178 
channel_forward_listen(ssh_session session,const char * address,int port,int * bound_port)179 int channel_forward_listen(ssh_session session, const char *address,
180     int port, int *bound_port){
181   return ssh_forward_listen(session, address, port, bound_port);
182 }
183 
channel_free(ssh_channel channel)184 void channel_free(ssh_channel channel){
185   ssh_channel_free(channel);
186 }
187 
channel_get_exit_status(ssh_channel channel)188 int channel_get_exit_status(ssh_channel channel){
189   return ssh_channel_get_exit_status(channel);
190 }
191 
channel_get_session(ssh_channel channel)192 ssh_session channel_get_session(ssh_channel channel){
193   return ssh_channel_get_session(channel);
194 }
195 
channel_is_closed(ssh_channel channel)196 int channel_is_closed(ssh_channel channel){
197   return ssh_channel_is_closed(channel);
198 }
199 
channel_is_eof(ssh_channel channel)200 int channel_is_eof(ssh_channel channel){
201   return ssh_channel_is_eof(channel);
202 }
203 
channel_is_open(ssh_channel channel)204 int channel_is_open(ssh_channel channel){
205   return ssh_channel_is_open(channel);
206 }
207 
channel_new(ssh_session session)208 ssh_channel channel_new(ssh_session session){
209   return ssh_channel_new(session);
210 }
211 
channel_open_forward(ssh_channel channel,const char * remotehost,int remoteport,const char * sourcehost,int localport)212 int channel_open_forward(ssh_channel channel, const char *remotehost,
213     int remoteport, const char *sourcehost, int localport){
214   return ssh_channel_open_forward(channel, remotehost, remoteport,
215       sourcehost,localport);
216 }
217 
channel_open_session(ssh_channel channel)218 int channel_open_session(ssh_channel channel){
219   return ssh_channel_open_session(channel);
220 }
221 
channel_poll(ssh_channel channel,int is_stderr)222 int channel_poll(ssh_channel channel, int is_stderr){
223   return ssh_channel_poll(channel, is_stderr);
224 }
225 
channel_read(ssh_channel channel,void * dest,uint32_t count,int is_stderr)226 int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr){
227   return ssh_channel_read(channel, dest, count, is_stderr);
228 }
229 
230 /*
231  * This function will completely be depreciated. The old implementation was not
232  * renamed.
233  * int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
234  *   int is_stderr);
235  */
236 
channel_read_nonblocking(ssh_channel channel,void * dest,uint32_t count,int is_stderr)237 int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
238     int is_stderr){
239   return ssh_channel_read_nonblocking(channel, dest, count, is_stderr);
240 }
241 
channel_request_env(ssh_channel channel,const char * name,const char * value)242 int channel_request_env(ssh_channel channel, const char *name, const char *value){
243   return ssh_channel_request_env(channel, name, value);
244 }
245 
channel_request_exec(ssh_channel channel,const char * cmd)246 int channel_request_exec(ssh_channel channel, const char *cmd){
247   return ssh_channel_request_exec(channel, cmd);
248 }
249 
channel_request_pty(ssh_channel channel)250 int channel_request_pty(ssh_channel channel){
251   return ssh_channel_request_pty(channel);
252 }
253 
channel_request_pty_size(ssh_channel channel,const char * term,int cols,int rows)254 int channel_request_pty_size(ssh_channel channel, const char *term,
255     int cols, int rows){
256   return ssh_channel_request_pty_size(channel, term, cols, rows);
257 }
258 
channel_request_shell(ssh_channel channel)259 int channel_request_shell(ssh_channel channel){
260   return ssh_channel_request_shell(channel);
261 }
262 
channel_request_send_signal(ssh_channel channel,const char * signum)263 int channel_request_send_signal(ssh_channel channel, const char *signum){
264   return ssh_channel_request_send_signal(channel, signum);
265 }
266 
channel_request_sftp(ssh_channel channel)267 int channel_request_sftp(ssh_channel channel){
268   return ssh_channel_request_sftp(channel);
269 }
270 
channel_request_subsystem(ssh_channel channel,const char * subsystem)271 int channel_request_subsystem(ssh_channel channel, const char *subsystem){
272   return ssh_channel_request_subsystem(channel, subsystem);
273 }
274 
channel_request_x11(ssh_channel channel,int single_connection,const char * protocol,const char * cookie,int screen_number)275 int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
276     const char *cookie, int screen_number){
277   return ssh_channel_request_x11(channel, single_connection, protocol, cookie,
278       screen_number);
279 }
280 
channel_send_eof(ssh_channel channel)281 int channel_send_eof(ssh_channel channel){
282   return ssh_channel_send_eof(channel);
283 }
284 
channel_select(ssh_channel * readchans,ssh_channel * writechans,ssh_channel * exceptchans,struct timeval * timeout)285 int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
286     timeval * timeout){
287   return ssh_channel_select(readchans, writechans, exceptchans, timeout);
288 }
289 
channel_set_blocking(ssh_channel channel,int blocking)290 void channel_set_blocking(ssh_channel channel, int blocking){
291   ssh_channel_set_blocking(channel, blocking);
292 }
293 
channel_write(ssh_channel channel,const void * data,uint32_t len)294 int channel_write(ssh_channel channel, const void *data, uint32_t len){
295   return ssh_channel_write(channel, data, len);
296 }
297 
298 /*
299  * These functions have to be wrapped around the pki.c functions.
300 
301 void privatekey_free(ssh_private_key prv);
302 ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
303     int type, const char *passphrase);
304 int ssh_publickey_to_file(ssh_session session, const char *file,
305     ssh_string pubkey, int type);
306 ssh_string publickey_to_string(ssh_public_key key);
307  *
308  */
309 
string_burn(ssh_string str)310 void string_burn(ssh_string str){
311   ssh_string_burn(str);
312 }
313 
string_copy(ssh_string str)314 ssh_string string_copy(ssh_string str){
315   return ssh_string_copy(str);
316 }
317 
string_data(ssh_string str)318 void *string_data(ssh_string str){
319   return ssh_string_data(str);
320 }
321 
string_fill(ssh_string str,const void * data,size_t len)322 int string_fill(ssh_string str, const void *data, size_t len){
323   return ssh_string_fill(str,data,len);
324 }
325 
string_free(ssh_string str)326 void string_free(ssh_string str){
327   ssh_string_free(str);
328 }
329 
string_from_char(const char * what)330 ssh_string string_from_char(const char *what){
331   return ssh_string_from_char(what);
332 }
333 
string_len(ssh_string str)334 size_t string_len(ssh_string str){
335   return ssh_string_len(str);
336 }
337 
string_new(size_t size)338 ssh_string string_new(size_t size){
339   return ssh_string_new(size);
340 }
341 
string_to_char(ssh_string str)342 char *string_to_char(ssh_string str){
343   return ssh_string_to_char(str);
344 }
345 
346 /* OLD PKI FUNCTIONS */
347 
publickey_free(ssh_public_key key)348 void publickey_free(ssh_public_key key) {
349   if (key == NULL) {
350     return;
351   }
352 
353   switch(key->type) {
354     case SSH_KEYTYPE_DSS:
355 #ifdef HAVE_LIBGCRYPT
356       gcry_sexp_release(key->dsa_pub);
357 #elif defined HAVE_LIBCRYPTO
358       DSA_free(key->dsa_pub);
359 #endif
360       break;
361     case SSH_KEYTYPE_RSA:
362     case SSH_KEYTYPE_RSA1:
363 #ifdef HAVE_LIBGCRYPT
364       gcry_sexp_release(key->rsa_pub);
365 #elif defined HAVE_LIBCRYPTO
366       RSA_free(key->rsa_pub);
367 #endif
368       break;
369     default:
370       break;
371   }
372   SAFE_FREE(key);
373 }
374 
publickey_from_privatekey(ssh_private_key prv)375 ssh_public_key publickey_from_privatekey(ssh_private_key prv) {
376     struct ssh_public_key_struct *p;
377     ssh_key privkey;
378     ssh_key pubkey;
379     int rc;
380 
381     privkey = ssh_key_new();
382     if (privkey == NULL) {
383         return NULL;
384     }
385 
386     privkey->type = prv->type;
387     privkey->type_c = ssh_key_type_to_char(privkey->type);
388     privkey->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
389     privkey->dsa = prv->dsa_priv;
390     privkey->rsa = prv->rsa_priv;
391 
392     rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
393     privkey->dsa = NULL;
394     privkey->rsa = NULL;
395     ssh_key_free(privkey);
396     if (rc < 0) {
397         return NULL;
398     }
399 
400     p = ssh_pki_convert_key_to_publickey(pubkey);
401     ssh_key_free(pubkey);
402 
403     return p;
404 }
405 
privatekey_from_file(ssh_session session,const char * filename,int type,const char * passphrase)406 ssh_private_key privatekey_from_file(ssh_session session,
407                                      const char *filename,
408                                      int type,
409                                      const char *passphrase) {
410     ssh_auth_callback auth_fn = NULL;
411     void *auth_data = NULL;
412     ssh_private_key privkey;
413     ssh_key key;
414     int rc;
415 
416     (void) type; /* unused */
417 
418     if (session->common.callbacks) {
419         auth_fn = session->common.callbacks->auth_function;
420         auth_data = session->common.callbacks->userdata;
421     }
422 
423 
424     rc = ssh_pki_import_privkey_file(filename,
425                                      passphrase,
426                                      auth_fn,
427                                      auth_data,
428                                      &key);
429     if (rc == SSH_ERROR) {
430         return NULL;
431     }
432 
433     privkey = malloc(sizeof(struct ssh_private_key_struct));
434     if (privkey == NULL) {
435         ssh_key_free(key);
436         return NULL;
437     }
438 
439     privkey->type = key->type;
440     privkey->dsa_priv = key->dsa;
441     privkey->rsa_priv = key->rsa;
442 
443     key->dsa = NULL;
444     key->rsa = NULL;
445 
446     ssh_key_free(key);
447 
448     return privkey;
449 }
450 
ssh_privatekey_type(ssh_private_key privatekey)451 enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey){
452   if (privatekey==NULL)
453     return SSH_KEYTYPE_UNKNOWN;
454   return privatekey->type;
455 }
456 
privatekey_free(ssh_private_key prv)457 void privatekey_free(ssh_private_key prv) {
458   if (prv == NULL) {
459     return;
460   }
461 
462 #ifdef HAVE_LIBGCRYPT
463   gcry_sexp_release(prv->dsa_priv);
464   gcry_sexp_release(prv->rsa_priv);
465 #elif defined HAVE_LIBCRYPTO
466   DSA_free(prv->dsa_priv);
467   RSA_free(prv->rsa_priv);
468 #endif
469   memset(prv, 0, sizeof(struct ssh_private_key_struct));
470   SAFE_FREE(prv);
471 }
472 
publickey_from_file(ssh_session session,const char * filename,int * type)473 ssh_string publickey_from_file(ssh_session session, const char *filename,
474     int *type) {
475     ssh_key key;
476     ssh_string key_str = NULL;
477     int rc;
478 
479     (void) session; /* unused */
480 
481     rc = ssh_pki_import_pubkey_file(filename, &key);
482     if (rc < 0) {
483         return NULL;
484     }
485 
486     rc = ssh_pki_export_pubkey_blob(key, &key_str);
487     if (rc < 0) {
488         return NULL;
489     }
490 
491     if (type) {
492         *type = key->type;
493     }
494     ssh_key_free(key);
495 
496     return key_str;
497 }
498 
ssh_type_to_char(int type)499 const char *ssh_type_to_char(int type) {
500     return ssh_key_type_to_char(type);
501 }
502 
ssh_type_from_name(const char * name)503 int ssh_type_from_name(const char *name) {
504     return ssh_key_type_from_name(name);
505 }
506 
publickey_from_string(ssh_session session,ssh_string pubkey_s)507 ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) {
508     struct ssh_public_key_struct *pubkey;
509     ssh_key key;
510     int rc;
511 
512     (void) session; /* unused */
513 
514     rc = ssh_pki_import_pubkey_blob(pubkey_s, &key);
515     if (rc < 0) {
516         return NULL;
517     }
518 
519     pubkey = malloc(sizeof(struct ssh_public_key_struct));
520     if (pubkey == NULL) {
521         ssh_key_free(key);
522         return NULL;
523     }
524 
525     pubkey->type = key->type;
526     pubkey->type_c = key->type_c;
527 
528     pubkey->dsa_pub = key->dsa;
529     key->dsa = NULL;
530     pubkey->rsa_pub = key->rsa;
531     key->rsa = NULL;
532 
533     ssh_key_free(key);
534 
535     return pubkey;
536 }
537 
publickey_to_string(ssh_public_key pubkey)538 ssh_string publickey_to_string(ssh_public_key pubkey) {
539     ssh_key key;
540     ssh_string key_blob;
541     int rc;
542 
543     key = ssh_key_new();
544     if (key == NULL) {
545         return NULL;
546     }
547 
548     key->type = pubkey->type;
549     key->type_c = pubkey->type_c;
550 
551     key->dsa = pubkey->dsa_pub;
552     key->rsa = pubkey->rsa_pub;
553 
554     rc = ssh_pki_export_pubkey_blob(key, &key_blob);
555     if (rc < 0) {
556         key_blob = NULL;
557     }
558 
559     key->dsa = NULL;
560     key->rsa = NULL;
561     ssh_key_free(key);
562 
563     return key_blob;
564 }
565 
ssh_publickey_to_file(ssh_session session,const char * file,ssh_string pubkey,int type)566 int ssh_publickey_to_file(ssh_session session,
567                           const char *file,
568                           ssh_string pubkey,
569                           int type)
570 {
571     FILE *fp;
572     char *user;
573     char buffer[1024];
574     char host[256];
575     unsigned char *pubkey_64;
576     size_t len;
577     int rc;
578     if(session==NULL)
579         return SSH_ERROR;
580     if(file==NULL || pubkey==NULL){
581         ssh_set_error(session, SSH_FATAL, "Invalid parameters");
582         return SSH_ERROR;
583     }
584     pubkey_64 = bin_to_base64(string_data(pubkey), ssh_string_len(pubkey));
585     if (pubkey_64 == NULL) {
586         return SSH_ERROR;
587     }
588 
589     user = ssh_get_local_username();
590     if (user == NULL) {
591         SAFE_FREE(pubkey_64);
592         return SSH_ERROR;
593     }
594 
595     rc = gethostname(host, sizeof(host));
596     if (rc < 0) {
597         SAFE_FREE(user);
598         SAFE_FREE(pubkey_64);
599         return SSH_ERROR;
600     }
601 
602     snprintf(buffer, sizeof(buffer), "%s %s %s@%s\n",
603             ssh_type_to_char(type),
604             pubkey_64,
605             user,
606             host);
607 
608     SAFE_FREE(pubkey_64);
609     SAFE_FREE(user);
610 
611     ssh_log(session, SSH_LOG_RARE, "Trying to write public key file: %s", file);
612     ssh_log(session, SSH_LOG_PACKET, "public key file content: %s", buffer);
613 
614     fp = fopen(file, "w+");
615     if (fp == NULL) {
616         ssh_set_error(session, SSH_REQUEST_DENIED,
617                 "Error opening %s: %s", file, strerror(errno));
618         return SSH_ERROR;
619     }
620 
621     len = strlen(buffer);
622     if (fwrite(buffer, len, 1, fp) != 1 || ferror(fp)) {
623         ssh_set_error(session, SSH_REQUEST_DENIED,
624                 "Unable to write to %s", file);
625         fclose(fp);
626         unlink(file);
627         return SSH_ERROR;
628     }
629 
630     fclose(fp);
631     return SSH_OK;
632 }
633 
ssh_try_publickey_from_file(ssh_session session,const char * keyfile,ssh_string * publickey,int * type)634 int ssh_try_publickey_from_file(ssh_session session,
635                                 const char *keyfile,
636                                 ssh_string *publickey,
637                                 int *type) {
638     char *pubkey_file;
639     size_t len;
640     ssh_string pubkey_string;
641     int pubkey_type;
642 
643     if (session == NULL || keyfile == NULL || publickey == NULL || type == NULL) {
644         return -1;
645     }
646 
647     if (session->sshdir == NULL) {
648         if (ssh_options_apply(session) < 0) {
649             return -1;
650         }
651     }
652 
653     ssh_log(session, SSH_LOG_PACKET, "Trying to open privatekey %s", keyfile);
654     if (!ssh_file_readaccess_ok(keyfile)) {
655         ssh_log(session, SSH_LOG_PACKET, "Failed to open privatekey %s", keyfile);
656         return -1;
657     }
658 
659     len = strlen(keyfile) + 5;
660     pubkey_file = malloc(len);
661     if (pubkey_file == NULL) {
662         return -1;
663     }
664     snprintf(pubkey_file, len, "%s.pub", keyfile);
665 
666     ssh_log(session, SSH_LOG_PACKET, "Trying to open publickey %s",
667             pubkey_file);
668     if (!ssh_file_readaccess_ok(pubkey_file)) {
669         ssh_log(session, SSH_LOG_PACKET, "Failed to open publickey %s",
670                 pubkey_file);
671         SAFE_FREE(pubkey_file);
672         return 1;
673     }
674 
675     ssh_log(session, SSH_LOG_PACKET, "Success opening public and private key");
676 
677     /*
678      * We are sure both the private and public key file is readable. We return
679      * the public as a string, and the private filename as an argument
680      */
681     pubkey_string = publickey_from_file(session, pubkey_file, &pubkey_type);
682     if (pubkey_string == NULL) {
683         ssh_log(session, SSH_LOG_PACKET,
684                 "Wasn't able to open public key file %s: %s",
685                 pubkey_file,
686                 ssh_get_error(session));
687         SAFE_FREE(pubkey_file);
688         return -1;
689     }
690 
691     SAFE_FREE(pubkey_file);
692 
693     *publickey = pubkey_string;
694     *type = pubkey_type;
695 
696     return 0;
697 }
698 
ssh_get_pubkey(ssh_session session)699 ssh_string ssh_get_pubkey(ssh_session session){
700 	if(session==NULL || session->current_crypto ==NULL ||
701       session->current_crypto->server_pubkey==NULL)
702     return NULL;
703 	else
704     return ssh_string_copy(session->current_crypto->server_pubkey);
705 }
706 
707 /****************************************************************************
708  * SERVER SUPPORT
709  ****************************************************************************/
710 
711 #ifdef WITH_SERVER
ssh_accept(ssh_session session)712 int ssh_accept(ssh_session session) {
713     return ssh_handle_key_exchange(session);
714 }
715 
channel_write_stderr(ssh_channel channel,const void * data,uint32_t len)716 int channel_write_stderr(ssh_channel channel, const void *data, uint32_t len) {
717     return ssh_channel_write(channel, data, len);
718 }
719 
720 /** @deprecated
721  * @brief Interface previously exported by error.
722  */
ssh_message_retrieve(ssh_session session,uint32_t packettype)723 ssh_message ssh_message_retrieve(ssh_session session, uint32_t packettype){
724 	(void) packettype;
725 	ssh_set_error(session, SSH_FATAL, "ssh_message_retrieve: obsolete libssh call");
726 	return NULL;
727 }
728 
729 #endif /* WITH_SERVER */
730