diff options
Diffstat (limited to 'sftp_server')
-rw-r--r-- | sftp_server/Makefile | 4 | ||||
-rw-r--r-- | sftp_server/Makefile.in | 2 | ||||
-rw-r--r-- | sftp_server/config.c | 93 | ||||
-rw-r--r-- | sftp_server/list.c | 2 | ||||
-rw-r--r-- | sftp_server/main.c | 102 | ||||
-rw-r--r-- | sftp_server/server.h | 9 |
6 files changed, 187 insertions, 25 deletions
diff --git a/sftp_server/Makefile b/sftp_server/Makefile index acc1c6a2..22f29309 100644 --- a/sftp_server/Makefile +++ b/sftp_server/Makefile @@ -14,9 +14,9 @@ libdir = $(prefix)/lib/ mandir = $(prefix)/man/man1 CC = gcc -CFLAGS = -g -O2 -Wall -g -I../include/ -Ilibconfig/ +CFLAGS = -Wall -g -I../include/ -Ilibconfig/ LDFLAGS = -L../libssh/ -lssh -Llibconfig/ -LIBS = -lz -lcrypto -lconfig +LIBS = -lz -lcrypto -lconfig -lpam -lcrypto INSTALL = /usr/bin/install -c DYLIB_EXTENSION = so LIBSSH_LDFLAGS = -shared diff --git a/sftp_server/Makefile.in b/sftp_server/Makefile.in index 295410c2..18931231 100644 --- a/sftp_server/Makefile.in +++ b/sftp_server/Makefile.in @@ -16,7 +16,7 @@ mandir = $(prefix)/man/man1 CC = @CC@ CFLAGS = @CFLAGS@ -Wall -g -I../include/ -Ilibconfig/ LDFLAGS = -L../libssh/ -lssh -Llibconfig/ -LIBS = @LIBS@ -lconfig +LIBS = @LIBS@ -lconfig -lpam -lcrypto INSTALL = @INSTALL@ DYLIB_EXTENSION = @DYLIB_EXTENSION@ LIBSSH_LDFLAGS = @LIBSSH_LDFLAGS@ diff --git a/sftp_server/config.c b/sftp_server/config.c index 0f735c2c..be69d077 100644 --- a/sftp_server/config.c +++ b/sftp_server/config.c @@ -23,6 +23,7 @@ MA 02111-1307, USA. */ #include <stdio.h> #include <unistd.h> #include <string.h> +#include <stdlib.h> #include "server.h" /* shortvar is "port" in "port 22" */ @@ -32,6 +33,7 @@ char *rsa=NULL; list *groups; list *users; +struct dir *root_dir=NULL; /* users is a list of users. The key of this list is the user name. the data of the list is a list of groups. both data & key from this list is the group name */ @@ -137,17 +139,47 @@ int group_callback(const char *shortvar, const char *var, const char *arguments, } return LC_CBRET_OKAY; } +struct dir *create_directory(const char *directory); +struct dir *current_dir=NULL; +int append_groups(list **plist, const char *groups){ + char *begin=strdup(groups); + char *ptr; + char *grp=begin; + do{ + ptr=strchr(grp,','); + if(ptr){ + *ptr=0; + ++ptr; + } + while(*grp==' ') + ++grp; + if(!list_find(*plist,grp)) + *plist=list_add(*plist,grp,strdup(grp)); + grp=ptr; + } while (grp); + return 0; +} int dir_callback(const char *shortvar, const char *var, const char *arguments, const char *value, lc_flags_t flags, void *extra){ switch(flags){ case LC_FLAGS_SECTIONSTART: - printf("new dir %s\n",arguments); + if(current_dir){ + printf("Cannot define a directory into a directory !\n"); + return LC_CBRET_ERROR; + } + current_dir=create_directory(arguments); break; case LC_FLAGS_SECTIONEND: - printf("end of dir\n\n"); + current_dir=NULL; break; default: - printf("%s - %s\n",shortvar, value); + if(!strcasecmp(shortvar,"list")) + append_groups(¤t_dir->List,value); + if(!strcasecmp(shortvar,"read")) + append_groups(¤t_dir->Read,value); + if(!strcasecmp(shortvar,"write")) + append_groups(¤t_dir->Write,value); +// printf("%s - %s\n",shortvar, value); } return LC_CBRET_OKAY; } @@ -178,6 +210,61 @@ void list_config(){ } } +char **cut_directory(const char *dir){ + char *tmp=strdup(dir); + char *ptr; + char *ret[128]; + char **answer; + int i=0; + while(tmp && *tmp && i<128){ + while(*tmp=='/') + ++tmp; + ptr=strchr(tmp,'/'); + if(ptr){ + *ptr=0; + ++ptr; + } + ret[i]=strdup(tmp); + tmp=ptr; + i++; + } + answer=malloc((i+1)*sizeof(char *)); + memcpy(answer,ret,sizeof(char *)*i); + answer[i]=NULL; + return answer; +} + +struct dir *dir_new(){ + struct dir *dir=malloc(sizeof(struct dir)); + memset(dir,0,sizeof(*dir)); + return dir; +} +/* it doesn't really create the directory. it makes the tree to the directory + * and returns a link to the last node */ +struct dir *create_directory(const char *directory){ + char **tokens=cut_directory(directory); + int i=0; + struct dir *dir,*ptr; + if(!root_dir){ + root_dir=dir_new(); + root_dir->name=""; + } + dir=root_dir; + for(i=0;tokens[i];++i){ + ptr=list_find(dir->subdir,tokens[i]); + if(!ptr){ + ptr=dir_new(); + ptr->name=strdup(tokens[i]); + dir->subdir=list_add(dir->subdir,tokens[i],ptr); + } + dir=ptr; + } + for(i=0;tokens[i];++i) + free(tokens[i]); + free(tokens); + return dir; +} + int parse_config(char *file){ int r; printf("Parsing configuration file %s\n",file); diff --git a/sftp_server/list.c b/sftp_server/list.c index b14126c2..4ab7bfcc 100644 --- a/sftp_server/list.c +++ b/sftp_server/list.c @@ -22,6 +22,8 @@ MA 02111-1307, USA. */ #include <stdio.h> #include <string.h> #include <unistd.h> +#include <stdlib.h> + list *list_add(list *ptr, const char *key, void *data){ list *new=malloc(sizeof(list)); new->next=ptr; diff --git a/sftp_server/main.c b/sftp_server/main.c index 817f89a3..c7e8c866 100644 --- a/sftp_server/main.c +++ b/sftp_server/main.c @@ -33,8 +33,12 @@ MA 02111-1307, USA. */ #include <errno.h> #include <fcntl.h> #include <stdio.h> +#include <security/pam_appl.h> + #include "server.h" +#define SERVICE "sftp" + #define TYPE_DIR 1 #define TYPE_FILE 1 struct sftp_handle { @@ -46,12 +50,61 @@ struct sftp_handle { FILE *file; }; +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; +} + + +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){ - if(strcmp(user,"aris")) - return 0; - if(strcmp(password,"lala")) + 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); + return 1; + } else { + pam_end(pamh,PAM_AUTH_ERR); return 0; - return 1; // authenticated + } } int reply_status(SFTP_CLIENT_MESSAGE *msg){ @@ -388,7 +441,7 @@ int sftploop(SSH_SESSION *session, SFTP_SESSION *sftp){ int do_auth(SSH_SESSION *session){ SSH_MESSAGE *message; - int auth=0; + int auth=-1; do { message=ssh_message_get(session); if(!message) @@ -397,20 +450,31 @@ int do_auth(SSH_SESSION *session){ case SSH_AUTH_REQUEST: switch(ssh_message_subtype(message)){ case SSH_AUTH_PASSWORD: - printf("User %s wants to auth with pass %s\n", - ssh_message_auth_user(message), - ssh_message_auth_password(message)); - if(auth_password(ssh_message_auth_user(message), - ssh_message_auth_password(message))){ - auth=1; - ssh_message_auth_reply_success(message,0); - break; - } + 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; // not authenticated, send default message case SSH_AUTH_NONE: - ssh_message_auth_reply_success(message,0); - auth=1; - break; + //ssh_message_auth_reply_success(message,0); + //auth=1; + //break; default: ssh_message_auth_set_methods(message,SSH_AUTH_PASSWORD); ssh_message_reply_default(message); @@ -421,7 +485,7 @@ int do_auth(SSH_SESSION *session){ ssh_message_reply_default(message); } ssh_message_free(message); - } while (!auth); + } while (auth!=1); return auth; } @@ -492,7 +556,7 @@ int main(int argc, char **argv){ printf("ssh_accept : %s\n",ssh_get_error(session)); return 1; } - if(do_auth(session)<=0){ + if(do_auth(session)<0){ printf("error : %s\n",ssh_get_error(session)); return 1; } diff --git a/sftp_server/server.h b/sftp_server/server.h index b211ca73..866eb70c 100644 --- a/sftp_server/server.h +++ b/sftp_server/server.h @@ -18,3 +18,12 @@ struct group { char *uid; char *gid; }; + +struct dir { + char *name; + list *subdir; + list *List; + list *Read; + list *Write; +}; + |