// Connect to a SSH server. // When the connection is established, read data from stdin and send it to the server. void client_pipe(char *host, int port) { ssh_session s = ssh_new(); ssh_options_set(s, SSH_OPTIONS_HOST, host); ssh_options_set(s, SSH_OPTIONS_PORT, &port); ssh_options_set(s, SSH_OPTIONS_USER, "xya"); //ssh_options_set(s, SSH_OPTIONS_LOG_VERBOSITY_STR, "5"); if(ssh_connect(s) != SSH_OK) return session_error(s, "connect"); char *hash = pubkey_hash(ssh_get_pubkey(s)); if(authenticate(hash, 0)) { session_event(s, "authenticated", hash); free(hash); } else { free(hash); exit(1); } int keytype; ssh_string pub = publickey_from_file(s, "test-client-key.pub", &keytype); if(!pub) session_error(s, "open-public-key"); if(SSH_AUTH_SUCCESS != ssh_userauth_offer_pubkey(s, NULL, keytype, pub)) session_error(s, "offer-public-key"); ssh_private_key priv = privatekey_from_file(s, "test-client-key", keytype, NULL); if(!priv) session_error(s, "open-private-key"); if(SSH_AUTH_SUCCESS != ssh_userauth_pubkey(s, NULL, pub, priv)) session_error(s, "user-auth"); string_free(pub); privatekey_free(priv); ssh_channel chan = channel_new(s); if(!chan) session_error(s, "create-channel"); if(channel_open_session(chan) < 0) session_error(s, "open-channel"); session_event(s, "channel-opened", NULL); channel_from_file(chan, 0); channel_free(chan); ssh_disconnect(s); ssh_finalize(); }
int ssh_userauth_autopubkey(SSH_SESSION *session){ int count=1; /* bypass identity */ int type=0; int err; STRING *pubkey; char *privkeyfile=NULL; PRIVATE_KEY *privkey; char *id=NULL; enter_function(); // always testing none err=ssh_userauth_none(session,NULL); if(err==SSH_AUTH_ERROR || err==SSH_AUTH_SUCCESS){ leave_function(); return err; } if(session->options->identity){ ssh_say(2,"Trying identity file %s\n",session->options->identity); keys_path[0]=session->options->identity; /* let's hope alloca exists */ id=malloc(strlen(session->options->identity)+1 + 4); sprintf(id,"%s.pub",session->options->identity); pub_keys_path[0]=id; count =0; } while((pubkey=publickey_from_next_file(session,pub_keys_path,keys_path, &privkeyfile,&type,&count))){ err=ssh_userauth_offer_pubkey(session,NULL,type,pubkey); if(err==SSH_AUTH_ERROR){ if(id){ pub_keys_path[0]=NULL; keys_path[0]=NULL; free(id); } free(pubkey); free(privkeyfile); leave_function(); return err; } else if(err != SSH_AUTH_SUCCESS){ ssh_say(2,"Public key refused by server\n"); free(pubkey); pubkey=NULL; free(privkeyfile); privkeyfile=NULL; continue; } /* pubkey accepted by server ! */ privkey=privatekey_from_file(session,privkeyfile,type,NULL); if(!privkey){ ssh_say(0,"Reading private key %s failed (bad passphrase ?)\n",privkeyfile); free(pubkey); pubkey=NULL; free(privkeyfile); privkeyfile=NULL; continue; /* continue the loop with other pubkey */ } err=ssh_userauth_pubkey(session,NULL,pubkey,privkey); if(err==SSH_AUTH_ERROR){ if(id){ pub_keys_path[0]=NULL; keys_path[0]=NULL; free(id); } free(pubkey); free(privkeyfile); private_key_free(privkey); leave_function(); return err; } else if(err != SSH_AUTH_SUCCESS){ ssh_say(0,"Weird : server accepted our public key but refused the signature\nit might be a bug of libssh\n"); free(pubkey); pubkey=NULL; free(privkeyfile); privkeyfile=NULL; private_key_free(privkey); continue; } /* auth success */ ssh_say(1,"Authentication using %s success\n",privkeyfile); free(pubkey); private_key_free(privkey); free(privkeyfile); if(id){ pub_keys_path[0]=NULL; keys_path[0]=NULL; free(id); } leave_function(); return SSH_AUTH_SUCCESS; } /* at this point, pubkey is NULL and so is privkeyfile */ ssh_say(1,"Tried every public key, none matched\n"); ssh_set_error(session,SSH_NO_ERROR,"no public key matched"); if(id){ pub_keys_path[0]=NULL; keys_path[0]=NULL; free(id); } leave_function(); return SSH_AUTH_DENIED; }
/** * @brief Tries to automaticaly authenticate with public key and "none" * * It may fail, for instance it doesn't ask for a password and uses a default * asker for passphrases (in case the private key is encrypted). * * @param session The ssh session to authenticate with. * * @param passphrase Use this passphrase to unlock the privatekey. Use NULL * if you don't want to use a passphrase or the user * should be asked. * * @returns SSH_AUTH_ERROR: A serious error happened\n * SSH_AUTH_DENIED: Authentication failed: use another method\n * SSH_AUTH_PARTIAL: You've been partially authenticated, you still * have to use another method\n * SSH_AUTH_SUCCESS: Authentication success * * @see ssh_userauth_kbdint() * @see ssh_userauth_password() */ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) { struct ssh_iterator *it; ssh_private_key privkey; ssh_public_key pubkey; ssh_string pubkey_string; int type = 0; int rc; enter_function(); /* Always test none authentication */ rc = ssh_userauth_none(session, NULL); if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_SUCCESS) { leave_function(); return rc; } /* Try authentication with ssh-agent first */ #ifndef _WIN32 if (agent_is_running(session)) { char *privkey_file = NULL; ssh_log(session, SSH_LOG_RARE, "Trying to authenticate with SSH agent keys as user: %s", session->username); for (pubkey = agent_get_first_ident(session, &privkey_file); pubkey != NULL; pubkey = agent_get_next_ident(session, &privkey_file)) { ssh_log(session, SSH_LOG_RARE, "Trying identity %s", privkey_file); pubkey_string = publickey_to_string(pubkey); if (pubkey_string) { rc = ssh_userauth_offer_pubkey(session, NULL, pubkey->type, pubkey_string); string_free(pubkey_string); if (rc == SSH_AUTH_ERROR) { SAFE_FREE(privkey_file); publickey_free(pubkey); leave_function(); return rc; } else if (rc != SSH_AUTH_SUCCESS) { ssh_log(session, SSH_LOG_PROTOCOL, "Public key refused by server"); SAFE_FREE(privkey_file); publickey_free(pubkey); continue; } ssh_log(session, SSH_LOG_RARE, "Public key accepted"); /* pubkey accepted by server ! */ rc = ssh_userauth_agent_pubkey(session, NULL, pubkey); if (rc == SSH_AUTH_ERROR) { SAFE_FREE(privkey_file); publickey_free(pubkey); leave_function(); return rc; } else if (rc != SSH_AUTH_SUCCESS) { ssh_log(session, SSH_LOG_RARE, "Server accepted public key but refused the signature ;" " It might be a bug of libssh"); SAFE_FREE(privkey_file); publickey_free(pubkey); continue; } /* auth success */ ssh_log(session, SSH_LOG_PROTOCOL, "Authentication using %s success", privkey_file); SAFE_FREE(privkey_file); publickey_free(pubkey); leave_function(); return SSH_AUTH_SUCCESS; } /* if pubkey */ SAFE_FREE(privkey_file); publickey_free(pubkey); } /* for each privkey */ } /* if agent is running */ #endif for (it = ssh_list_get_iterator(session->identity); it != NULL; it = it->next) { const char *privkey_file = it->data; int privkey_open = 0; privkey = NULL; ssh_log(session, SSH_LOG_PROTOCOL, "Trying to read privatekey %s", privkey_file); rc = ssh_try_publickey_from_file(session, privkey_file, &pubkey_string, &type); if (rc == 1) { char *publickey_file; size_t len; privkey = privatekey_from_file(session, privkey_file, type, passphrase); if (privkey == NULL) { ssh_log(session, SSH_LOG_RARE, "Reading private key %s failed (bad passphrase ?)", privkey_file); leave_function(); return SSH_AUTH_ERROR; } privkey_open = 1; pubkey = publickey_from_privatekey(privkey); if (pubkey == NULL) { privatekey_free(privkey); ssh_set_error_oom(session); leave_function(); return SSH_AUTH_ERROR; } pubkey_string = publickey_to_string(pubkey); type = pubkey->type; publickey_free(pubkey); if (pubkey_string == NULL) { ssh_set_error_oom(session); leave_function(); return SSH_AUTH_ERROR; } len = strlen(privkey_file) + 5; publickey_file = malloc(len); if (publickey_file == NULL) { ssh_set_error_oom(session); leave_function(); return SSH_AUTH_ERROR; } snprintf(publickey_file, len, "%s.pub", privkey_file); rc = ssh_publickey_to_file(session, publickey_file, pubkey_string, type); if (rc < 0) { ssh_log(session, SSH_LOG_PACKET, "Could not write public key to file: %s", publickey_file); } SAFE_FREE(publickey_file); } else if (rc < 0) { continue; } rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey_string); if (rc == SSH_AUTH_ERROR){ string_free(pubkey_string); ssh_log(session, SSH_LOG_RARE, "Publickey authentication error"); leave_function(); return rc; } else { if (rc != SSH_AUTH_SUCCESS){ ssh_log(session, SSH_LOG_PROTOCOL, "Publickey refused by server"); string_free(pubkey_string); continue; } } /* Public key accepted by server! */ if (!privkey_open) { ssh_log(session, SSH_LOG_PROTOCOL, "Trying to read privatekey %s", privkey_file); privkey = privatekey_from_file(session, privkey_file, type, passphrase); if (privkey == NULL) { ssh_log(session, SSH_LOG_RARE, "Reading private key %s failed (bad passphrase ?)", privkey_file); string_free(pubkey_string); continue; /* continue the loop with other pubkey */ } } rc = ssh_userauth_pubkey(session, NULL, pubkey_string, privkey); if (rc == SSH_AUTH_ERROR) { string_free(pubkey_string); privatekey_free(privkey); leave_function(); return rc; } else { if (rc != SSH_AUTH_SUCCESS){ ssh_log(session, SSH_LOG_FUNCTIONS, "The server accepted the public key but refused the signature"); string_free(pubkey_string); privatekey_free(privkey); continue; } } /* auth success */ ssh_log(session, SSH_LOG_PROTOCOL, "Successfully authenticated using %s", privkey_file); string_free(pubkey_string); privatekey_free(privkey); leave_function(); return SSH_AUTH_SUCCESS; } /* at this point, pubkey is NULL and so is privkeyfile */ ssh_log(session, SSH_LOG_FUNCTIONS, "Tried every public key, none matched"); ssh_set_error(session,SSH_NO_ERROR,"No public key matched"); leave_function(); return SSH_AUTH_DENIED; }