1
1

the server now does the chroot and change uid.

There is also an option "nopassword" for ftp users.


git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@25 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
Aris Adamantiadis 2005-08-29 14:29:07 +00:00
родитель ddd650b3bd
Коммит bcb6bf25fa
4 изменённых файлов: 136 добавлений и 5 удалений

Просмотреть файл

@ -136,6 +136,8 @@ int group_callback(const char *shortvar, const char *var, const char *arguments,
if(!strcasecmp(shortvar,"chroot")){
current_group->chroot=strdup(value);
}
if(!strcasecmp(shortvar,"nopassword"))
current_group->nopassword=1;
}
return LC_CBRET_OKAY;
}
@ -278,6 +280,7 @@ int parse_config(char *file){
r=lc_register_callback("group.uid",0,LC_VAR_UNKNOWN,group_callback,NULL);
r=lc_register_callback("group.chroot",0,LC_VAR_UNKNOWN,group_callback,NULL);
r=lc_register_callback("group.group",0,LC_VAR_UNKNOWN,group_callback,NULL);
r=lc_register_callback("group.nopassword",0,LC_VAR_NONE,group_callback,NULL);
// lc_register_var("dir", LC_VAR_SECTION, NULL, 0);
r=lc_register_callback("dir",0,LC_VAR_NONE,dir_callback,NULL);
r=lc_register_callback("dir.list",0,LC_VAR_UNKNOWN,dir_callback,NULL);
@ -291,3 +294,52 @@ int parse_config(char *file){
list_config();
return 0;
}
list *find_groups(char *user){
return list_find(users,user);
}
char *user_chroot(char *user){
char *c_grp;
list *group=find_groups(user);
struct group *grp;
while(group){
c_grp=group->key;
grp=list_find(groups,c_grp);
if(grp->chroot)
return grp->chroot;
group=group->next;
}
return NULL;
}
char *user_uid(char *user){
char *c_grp;
list *group=find_groups(user);
struct group *grp;
while(group){
c_grp=group->key;
grp=list_find(groups,c_grp);
if(grp->uid)
return grp->uid;
group=group->next;
}
return NULL;
}
/* 0 if it's not specified. 1 if the user doesn't need a password */
int user_nopassword(char *user){
char *c_grp;
list *group=find_groups(user);
struct group *grp;
if(!group)
return 0; //user doesn't exist
while(group){
c_grp=group->key;
grp=list_find(groups,c_grp);
if(grp->nopassword)
return 1;
group=group->next;
}
return 0;
}

Просмотреть файл

@ -35,6 +35,7 @@ MA 02111-1307, USA. */
#include <stdio.h>
#include <signal.h>
#include <security/pam_appl.h>
#include <pwd.h>
#include "server.h"
@ -81,7 +82,59 @@ int password_conv(int num_msg, const struct pam_message **msg,
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 */
@ -101,6 +154,8 @@ int auth_password(char *user, char *password){
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);
@ -469,13 +524,32 @@ int do_auth(SSH_SESSION *session){
ssh_say(1,"Auth refused\n");
break;
}
if(auth==1)
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:
//ssh_message_auth_reply_success(message,0);
//auth=1;
//break;
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);

Просмотреть файл

@ -1,6 +1,9 @@
/* server.h */
/* headers for the sftp server project */
int parse_config(char *file);
char *user_chroot(char *user);
char *user_uid(char *user);
int user_nopassword(char *user);
typedef struct list_struct {
struct list_struct *next;
@ -17,6 +20,7 @@ struct group {
char *chroot;
char *uid;
char *gid;
int nopassword;
};
struct dir {

Просмотреть файл

@ -8,6 +8,7 @@ Hostkeydsa /etc/ssh/ssh_host_dsa_key
<group anonymous>
user ftp, anonymous, anon
uid ftp
nopassword
chroot /home/ftp
</group>
<group users>