aboutsummaryrefslogtreecommitdiff
path: root/sftp_server
diff options
context:
space:
mode:
Diffstat (limited to 'sftp_server')
-rw-r--r--sftp_server/Makefile4
-rw-r--r--sftp_server/Makefile.in2
-rw-r--r--sftp_server/config.c93
-rw-r--r--sftp_server/list.c2
-rw-r--r--sftp_server/main.c102
-rw-r--r--sftp_server/server.h9
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(&current_dir->List,value);
+ if(!strcasecmp(shortvar,"read"))
+ append_groups(&current_dir->Read,value);
+ if(!strcasecmp(shortvar,"write"))
+ append_groups(&current_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;
+};
+