/[LeafOK_CVS]/lbbs/src/net_server.c
ViewVC logotype

Diff of /lbbs/src/net_server.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.53 by sysadm, Thu Jun 5 09:04:55 2025 UTC Revision 1.60 by sysadm, Tue Jun 17 01:24:21 2025 UTC
# Line 20  Line 20 
20    
21  #include "net_server.h"  #include "net_server.h"
22  #include "common.h"  #include "common.h"
23    #include "bbs_main.h"
24    #include "bbs.h"
25  #include "log.h"  #include "log.h"
26  #include "io.h"  #include "io.h"
27  #include "init.h"  #include "init.h"
 #include "fork.h"  
28  #include "menu.h"  #include "menu.h"
29    #include "database.h"
30    #include "login.h"
31  #include "file_loader.h"  #include "file_loader.h"
32  #include "section_list_loader.h"  #include "section_list_loader.h"
33  #include <errno.h>  #include <errno.h>
# Line 40  Line 43 
43  #include <arpa/inet.h>  #include <arpa/inet.h>
44  #include <netinet/in.h>  #include <netinet/in.h>
45  #include <systemd/sd-daemon.h>  #include <systemd/sd-daemon.h>
46    #include <libssh/libssh.h>
47    #include <libssh/server.h>
48    #include <libssh/callbacks.h>
49    
50  struct process_sockaddr_t  struct process_sockaddr_t
51  {  {
# Line 50  typedef struct process_sockaddr_t PROCES Line 56  typedef struct process_sockaddr_t PROCES
56    
57  static PROCESS_SOCKADDR process_sockaddr_pool[MAX_CLIENT_LIMIT];  static PROCESS_SOCKADDR process_sockaddr_pool[MAX_CLIENT_LIMIT];
58    
59    #define SSH_AUTH_MAX_DURATION (60 * 1000) // milliseconds
60    
61    struct ssl_server_cb_data_t
62    {
63            int tries;
64            int error;
65    };
66    
67    static int auth_password(ssh_session session, const char *user,
68                                                     const char *password, void *userdata)
69    {
70            struct ssl_server_cb_data_t *p_data = userdata;
71            int ret;
72    
73            if (strcmp(user, "guest") == 0)
74            {
75                    ret = load_guest_info();
76            }
77            else
78            {
79                    ret = check_user(user, password);
80            }
81    
82            if (ret == 0)
83            {
84                    return SSH_AUTH_SUCCESS;
85            }
86    
87            if ((++(p_data->tries)) >= BBS_login_retry_times)
88            {
89                    p_data->error = 1;
90            }
91    
92            return SSH_AUTH_DENIED;
93    }
94    
95    static int pty_request(ssh_session session, ssh_channel channel, const char *term,
96                                               int x, int y, int px, int py, void *userdata)
97    {
98            return 0;
99    }
100    
101    static int shell_request(ssh_session session, ssh_channel channel, void *userdata)
102    {
103            return 0;
104    }
105    
106    static struct ssh_channel_callbacks_struct channel_cb = {
107            .channel_pty_request_function = pty_request,
108            .channel_shell_request_function = shell_request};
109    
110    static ssh_channel new_session_channel(ssh_session session, void *userdata)
111    {
112            if (SSH_channel != NULL)
113            {
114                    return NULL;
115            }
116    
117            SSH_channel = ssh_channel_new(session);
118            ssh_callbacks_init(&channel_cb);
119            ssh_set_channel_callbacks(SSH_channel, &channel_cb);
120    
121            return SSH_channel;
122    }
123    
124    static int fork_server(void)
125    {
126            ssh_event event;
127            int pid;
128            int i;
129            int ret;
130    
131            struct ssl_server_cb_data_t cb_data = {
132                    .tries = 0,
133                    .error = 0,
134            };
135    
136            struct ssh_server_callbacks_struct cb = {
137                    .userdata = &cb_data,
138                    .auth_password_function = auth_password,
139                    .channel_open_request_session_function = new_session_channel,
140            };
141    
142            pid = fork();
143    
144            if (pid > 0) // Parent process
145            {
146                    SYS_child_process_count++;
147                    log_common("Child process (%d) start\n", pid);
148                    return pid;
149            }
150            else if (pid < 0) // Error
151            {
152                    log_error("fork() error (%d)\n", errno);
153                    return -1;
154            }
155    
156            // Child process
157    
158            if (close(socket_server[0]) == -1 || close(socket_server[1]) == -1)
159            {
160                    log_error("Close server socket failed\n");
161            }
162    
163            SSH_session = ssh_new();
164    
165            if (SSH_v2)
166            {
167                    if (ssh_bind_accept_fd(sshbind, SSH_session, socket_client) != SSH_OK)
168                    {
169                            log_error("ssh_bind_accept_fd() error: %s\n", ssh_get_error(SSH_session));
170                            goto cleanup;
171                    }
172    
173                    ssh_bind_free(sshbind);
174    
175                    ssh_callbacks_init(&cb);
176                    ssh_set_server_callbacks(SSH_session, &cb);
177    
178                    if (ssh_handle_key_exchange(SSH_session))
179                    {
180                            log_error("ssh_handle_key_exchange() error: %s\n", ssh_get_error(SSH_session));
181                            goto cleanup;
182                    }
183                    ssh_set_auth_methods(SSH_session, SSH_AUTH_METHOD_PASSWORD);
184    
185                    event = ssh_event_new();
186                    ssh_event_add_session(event, SSH_session);
187    
188                    for (i = 0; i < SSH_AUTH_MAX_DURATION && !SYS_server_exit && !cb_data.error && SSH_channel == NULL; i += 100)
189                    {
190                            ret = ssh_event_dopoll(event, 100); // 0.1 second
191                            if (ret == SSH_ERROR)
192                            {
193                                    log_error("ssh_event_dopoll() error: %s\n", ssh_get_error(SSH_session));
194                                    goto cleanup;
195                            }
196                    }
197    
198                    if (cb_data.error)
199                    {
200                            log_error("SSH auth error, tried %d times\n", cb_data.tries);
201                            goto cleanup;
202                    }
203            }
204    
205            // Redirect Input
206            close(STDIN_FILENO);
207            if (dup2(socket_client, STDIN_FILENO) == -1)
208            {
209                    log_error("Redirect stdin to client socket failed\n");
210                    goto cleanup;
211            }
212    
213            // Redirect Output
214            close(STDOUT_FILENO);
215            if (dup2(socket_client, STDOUT_FILENO) == -1)
216            {
217                    log_error("Redirect stdout to client socket failed\n");
218                    goto cleanup;
219            }
220    
221            SYS_child_process_count = 0;
222    
223            bbs_main();
224    
225    cleanup:
226            // Child process exit
227            SYS_server_exit = 1;
228    
229            if (SSH_v2)
230            {
231                    ssh_channel_free(SSH_channel);
232                    ssh_disconnect(SSH_session);
233            }
234            else if (close(socket_client) == -1)
235            {
236                    log_error("Close client socket failed\n");
237            }
238    
239            ssh_free(SSH_session);
240            ssh_finalize();
241    
242            // Close Input and Output for client
243            close(STDIN_FILENO);
244            close(STDOUT_FILENO);
245    
246            log_common("Process exit normally\n");
247            log_end();
248    
249            _exit(0);
250    
251            return 0;
252    }
253    
254  int net_server(const char *hostaddr, in_port_t port[])  int net_server(const char *hostaddr, in_port_t port[])
255  {  {
256          unsigned int addrlen;          unsigned int addrlen;
# Line 324  int net_server(const char *hostaddr, in_ Line 525  int net_server(const char *hostaddr, in_
525    
526                                          port_client = ntohs(sin.sin_port);                                          port_client = ntohs(sin.sin_port);
527    
528                                          log_common("Accept connection from %s:%d\n", hostaddr_client, port_client);                                          log_common("Accept %sconnection from %s:%d\n", (SSH_v2 ? "" : "SSH2 "), hostaddr_client, port_client);
529    
530                                          if (SYS_child_process_count - 1 < BBS_max_client)                                          if (SYS_child_process_count - 1 < BBS_max_client)
531                                          {                                          {


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1