aboutsummaryrefslogtreecommitdiff
path: root/sftp_server/userauth.c
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2005-08-29 14:53:44 +0000
committerAris Adamantiadis <aris@0xbadc0de.be>2005-08-29 14:53:44 +0000
commitf31e7a3bec432be88aa4bb82c7f53baa32c6ac28 (patch)
tree0123e8e4cecf7f20a7cbe5ff06c94d35b3fd81c2 /sftp_server/userauth.c
parentbcb6bf25fa132421672d0782b9bfdb82fd2c6600 (diff)
downloadlibssh-f31e7a3bec432be88aa4bb82c7f53baa32c6ac28.tar.gz
libssh-f31e7a3bec432be88aa4bb82c7f53baa32c6ac28.tar.xz
libssh-f31e7a3bec432be88aa4bb82c7f53baa32c6ac28.zip
removed obsolete debugging info, split main.c in 3, and now mercurius links with a statical libssh
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@26 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'sftp_server/userauth.c')
-rw-r--r--sftp_server/userauth.c213
1 files changed, 213 insertions, 0 deletions
diff --git a/sftp_server/userauth.c b/sftp_server/userauth.c
new file mode 100644
index 00000000..37bdc04a
--- /dev/null
+++ b/sftp_server/userauth.c
@@ -0,0 +1,213 @@
+/* userauth.c */
+/* handle the authentication of the client */
+/*
+Copyright 2005 Aris Adamantiadis
+
+This file is part of the SSH Library
+
+The SSH Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+The SSH Library 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 Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the SSH Library; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <libssh/libssh.h>
+#include <libssh/server.h>
+//#include <libssh/sftp.h>
+#include <security/pam_appl.h>
+#include <pwd.h>
+#include <string.h>
+#include "server.h"
+
+#define SERVICE "sftp"
+
+char *user_password;
+int password_conv(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata)
+{
+ int i=0;
+ for(i=0;i<num_msg;++i){
+ resp[i]=malloc(sizeof (struct pam_response));
+ resp[i]->resp_retcode=0;
+ switch(msg[i]->msg_style){
+ case PAM_PROMPT_ECHO_ON:
+ //printf("PAM: %s",msg[i]->msg);
+ resp[i]->resp=strdup(user_password);
+ break;
+ case PAM_PROMPT_ECHO_OFF:
+ //printf("PAM: %s",msg[i]->msg);
+ resp[i]->resp=strdup(user_password);
+ break;
+ case PAM_ERROR_MSG:
+ //printf("PAM_ERROR: %s",msg[i]->msg);
+ break;
+ case PAM_TEXT_INFO:
+ //printf("PAM TEXT: %s",msg[i]->msg);
+ break;
+ default:
+ break;
+ }
+ }
+ return PAM_SUCCESS;
+}
+
+/* postauth_conf returns -1 on error, else 0 */
+int postauth_conf(char *user){
+ /* first, find a chroot if any */
+ char *root,*ptr;
+ char *char_uid;
+ char buffer[256];
+ int uid;
+ struct passwd *pw=getpwnam(user);
+ root=user_chroot(user);
+ if(root){
+ if((ptr=strstr(root,"$HOME"))){
+ if(!pw)
+ return -1; // this user has no user directory
+ *ptr=0;
+ snprintf(buffer,sizeof(buffer),"%s%s/%s",
+ root,pw->pw_dir,ptr+strlen("$HOME"));
+ }
+ else
+ snprintf(buffer,sizeof(buffer),"%s",root);
+ }
+ /* we don't chroot right now because we still need getpwnam() */
+ char_uid=user_uid(user);
+ if(!char_uid){
+ if(!pw)
+ return -1; // user doesn't exist !
+ char_uid=user;
+ }
+ uid=atoi(char_uid);
+ if(uid==0 && char_uid[0]!=0){
+ pw=getpwnam(char_uid);
+ if(!pw)
+ return -1;
+ uid=pw->pw_uid;
+ }
+ if(root && chroot(buffer)){
+ return -1; // cannot chroot
+ }
+ if(root){
+ chdir("/");
+ } else {
+ if(pw)
+ chdir(pw->pw_dir);
+ else
+ chdir("/");
+ }
+ if(setuid(uid)){
+ return -1; // cannot setuid
+ }
+ return 0;
+}
+
+
+
+struct pam_conv pam_conv ={ password_conv, NULL };
+/* returns 1 if authenticated, 0 if failed,
+ -1 if you must leave */
+int auth_password(char *user, char *password){
+ pam_handle_t *pamh;
+ int ret;
+ static int tries=0;
+ if(tries>3)
+ return -1;
+ tries++;
+ user_password=password;
+ ret=pam_start(SERVICE,user,&pam_conv,&pamh);
+ if(ret==PAM_SUCCESS)
+ ret=pam_authenticate(pamh,0);
+ if(ret==PAM_SUCCESS)
+ ret=pam_acct_mgmt(pamh,0);
+ memset(password,0,strlen(password));
+ if(ret==PAM_SUCCESS){
+ pam_end(pamh,PAM_SUCCESS);
+ if(postauth_conf(user))
+ return -1;
+ return 1;
+ } else {
+ pam_end(pamh,PAM_AUTH_ERR);
+ return 0;
+ }
+}
+
+
+
+int do_auth(SSH_SESSION *session){
+ SSH_MESSAGE *message;
+ int auth=-1;
+ do {
+ message=ssh_message_get(session);
+ if(!message)
+ break;
+ switch(ssh_message_type(message)){
+ case SSH_AUTH_REQUEST:
+ switch(ssh_message_subtype(message)){
+ case SSH_AUTH_PASSWORD:
+ ssh_say(1,"User %s wants to auth by password\n",
+ ssh_message_auth_user(message));
+ auth=auth_password(ssh_message_auth_user(message),
+ ssh_message_auth_password(message));
+ switch(auth){
+ case 1:
+ ssh_say(1,"Authentication success\n");
+ ssh_message_auth_reply_success(message,0);
+ break;
+ case -1:
+ ssh_say(1,"Too much tries\n");
+ // too much auth tried
+ ssh_disconnect(session);
+ exit(1);
+ case 0:
+ ssh_say(1,"Auth refused\n");
+ break;
+ }
+ if(auth==1){
+ break;
+ } else {
+ ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
+ ssh_message_reply_default(message);
+ }
+ break;
+ // not authenticated, send default message
+ case SSH_AUTH_NONE:
+ if(user_nopassword(ssh_message_auth_user(message))){
+ if(postauth_conf(ssh_message_auth_user(message))==0){
+ ssh_message_auth_reply_success(message,0);
+ auth=1;
+ ssh_say(1,"Authentication success for %s(no password)\n",
+ ssh_message_auth_user(message));
+ break;
+ } else {
+ ssh_say(1,"Post-auth failed\n");
+ ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
+ ssh_message_reply_default(message);
+ }
+ } else {
+ ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
+ ssh_message_reply_default(message);
+ }
+ break;
+ default:
+ ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD);
+ ssh_message_reply_default(message);
+ break;
+ }
+ break;
+ default:
+ ssh_message_reply_default(message);
+ }
+ ssh_message_free(message);
+ } while (auth!=1);
+ return auth;
+}