125
125
126
126
/* Privilege separation related spawn fds */
127
127
#ifdef WINDOWS
128
- #define PRIVSEP_UNAUTH_MIN_FREE_FD (PRIVSEP_LOG_FD + 1)
129
128
#define PRIVSEP_AUTH_MIN_FREE_FD (PRIVSEP_LOG_FD + 1)
130
129
#endif /* WINDOWS */
131
130
@@ -163,7 +162,6 @@ int auth_sock = -1;
163
162
static int have_agent = 0 ;
164
163
165
164
#ifdef WINDOWS
166
- int privsep_unauth_child = 0 ;
167
165
int privsep_auth_child = 0 ;
168
166
int io_sock_in = 0 ;
169
167
int io_sock_out = 0 ;
@@ -230,10 +228,14 @@ mm_is_monitor(void)
230
228
}
231
229
232
230
#ifdef WINDOWS
231
+ /* The following methods are needed to manage sending and receiving
232
+ information between sshd-session and sshd-auth processes.
233
+ Where applicable, the methods are copied from sshd.c.
234
+ */
233
235
static struct sshbuf *
234
236
pack_hostkeys_for_child (void )
235
237
{
236
- /* copied from sshd.c */
238
+ /* copied from pack_hostkeys() in sshd.c, used in send_config_state() */
237
239
struct sshbuf * m = NULL , * keybuf = NULL , * hostkeys = NULL ;
238
240
int r ;
239
241
u_int i ;
@@ -333,64 +335,8 @@ pack_config(struct sshbuf* conf)
333
335
static void
334
336
send_config_state (int fd , struct sshbuf * conf )
335
337
{
336
- // /* copied from send_rexec_state in sshd.c */
337
- // struct sshbuf* m = NULL, * inc = NULL, * hostkeys = NULL;
338
- // struct include_item* item = NULL;
339
- // int r, sz;
340
- //
341
- // debug3_f("entering fd = %d config len %zu", fd,
342
- // sshbuf_len(conf));
343
- //
344
- // if ((m = sshbuf_new()) == NULL ||
345
- // (inc = sshbuf_new()) == NULL)
346
- // fatal_f("sshbuf_new failed");
347
- //
348
- // /* pack includes into a string */
349
- // TAILQ_FOREACH(item, &includes, entry) {
350
- // if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 ||
351
- // (r = sshbuf_put_cstring(inc, item->filename)) != 0 ||
352
- // (r = sshbuf_put_stringb(inc, item->contents)) != 0)
353
- // fatal_fr(r, "compose includes");
354
- // }
355
- //
356
- // hostkeys = pack_hostkeys();
357
- //
358
- // /*
359
- // * Protocol from reexec master to child:
360
- // * string configuration
361
- // * uint64 timing_secret
362
- // * string host_keys[] {
363
- // * string private_key
364
- // * string public_key
365
- // * string certificate
366
- // * }
367
- // * string included_files[] {
368
- // * string selector
369
- // * string filename
370
- // * string contents
371
- // * }
372
- // */
373
- // if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
374
- // (r = sshbuf_put_u64(m, options.timing_secret)) != 0 ||
375
- // (r = sshbuf_put_stringb(m, hostkeys)) != 0 ||
376
- // (r = sshbuf_put_stringb(m, inc)) != 0)
377
- // fatal_fr(r, "compose config");
378
- //
379
- //#ifndef WINDOWS
380
- // /* We need to fit the entire message inside the socket send buffer */
381
- // sz = ROUNDUP(sshbuf_len(m) + 5, 16 * 1024);
382
- // if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof sz) == -1)
383
- // fatal_f("setsockopt SO_SNDBUF: %s", strerror(errno));
384
- //#endif /* WINDOWS */
385
- // if (ssh_msg_send(fd, 0, m) == -1)
386
- // error_f("ssh_msg_send failed");
387
- //
388
- // sshbuf_free(m);
389
- // sshbuf_free(inc);
390
- // sshbuf_free(hostkeys);
391
- //
392
- // debug3_f("done");
393
- /* copied from send_rexec_state in sshd.c */
338
+ /* copied from send_rexec_state() in sshd.c
339
+ On Windows, uses pack_hostkeys_for_child() and pack_config() */
394
340
struct sshbuf * keys ;
395
341
u_int mlen ;
396
342
#ifdef WINDOWS
@@ -561,61 +507,8 @@ send_hostkeys_state(int fd)
561
507
sshbuf_free (m );
562
508
}
563
509
564
- static void
565
- recv_hostkeys_state (int fd )
566
- {
567
- struct sshbuf * m ;
568
- u_char * cp , ver ;
569
- struct sshkey * key = NULL ;
570
- const u_char * blob ;
571
- size_t blen ;
572
- int r ;
573
- u_int32_t num_host_key_files ;
574
-
575
- debug3 ("%s: entering fd = %d" , __func__ , fd );
576
-
577
- if ((m = sshbuf_new ()) == NULL )
578
- fatal ("%s: sshbuf_new failed" , __func__ );
579
- if (ssh_msg_recv (fd , m ) == -1 )
580
- fatal ("%s: ssh_msg_recv failed" , __func__ );
581
- if ((r = sshbuf_get_u8 (m , & ver )) != 0 )
582
- fatal ("%s: buffer error: %s" , __func__ , ssh_err (r ));
583
- if (ver != 0 )
584
- fatal ("%s: rexec version mismatch" , __func__ );
585
-
586
- if ((r = sshbuf_get_u32 (m , & num_host_key_files )) != 0 )
587
- fatal ("%s: buffer error: %s" , __func__ , ssh_err (r ));
588
- sensitive_data .host_keys = xcalloc (num_host_key_files , sizeof (struct sshkey * ));
589
- sensitive_data .host_pubkeys = xcalloc (num_host_key_files , sizeof (struct sshkey * ));
590
- sensitive_data .host_certificates = xcalloc (num_host_key_files , sizeof (struct sshkey * ));
591
- for (int i = 0 ; i < num_host_key_files ; i ++ ) {
592
- if ((r = sshbuf_get_string_direct (m , & blob , & blen )) != 0 )
593
- fatal ("%s: buffer error: %s" , __func__ , ssh_err (r ));
594
- sensitive_data .host_pubkeys [i ] = NULL ;
595
- sensitive_data .host_keys [i ] = NULL ;
596
-
597
- if (blen ) {
598
- sshkey_from_blob (blob , blen , & key );
599
- sensitive_data .host_pubkeys [i ] = key ;
600
- }
601
- }
602
-
603
- for (int i = 0 ; i < num_host_key_files ; i ++ ) {
604
- if ((r = sshbuf_get_string_direct (m , & blob , & blen )) != 0 )
605
- fatal ("%s: buffer error: %s" , __func__ , ssh_err (r ));
606
- sensitive_data .host_certificates [i ] = NULL ;
607
- if (blen ) {
608
- sshkey_from_blob (blob , blen , & key );
609
- sensitive_data .host_certificates [i ] = key ;
610
- }
611
- }
612
-
613
- sshbuf_free (m );
614
- debug3 ("%s: done" , __func__ );
615
- }
616
-
617
510
static char * *
618
- privsep_child_cmdline (int authenticated )
511
+ privsep_child_cmdline ()
619
512
{
620
513
char * * argv = saved_argv ;
621
514
int argc = 0 ;
@@ -635,10 +528,7 @@ privsep_child_cmdline(int authenticated)
635
528
argc = saved_argc ;
636
529
}
637
530
638
- if (authenticated )
639
- argv [argc ] = "-z" ;
640
- else
641
- argv [argc ] = "-y" ;
531
+ argv [argc ] = "-z" ;
642
532
643
533
return argv ;
644
534
}
@@ -792,63 +682,6 @@ privsep_preauth(struct ssh *ssh)
792
682
authctxt -> valid = 1 ;
793
683
return 1 ;
794
684
}
795
- else if (privsep_unauth_child ) {
796
- close (pmonitor -> m_sendfd );
797
- close (pmonitor -> m_log_recvfd );
798
- close (pmonitor -> m_recvfd );
799
- close (pmonitor -> m_log_sendfd );
800
-
801
- pmonitor -> m_recvfd = PRIVSEP_MONITOR_FD ;
802
- pmonitor -> m_log_sendfd = PRIVSEP_LOG_FD ;
803
-
804
- fcntl (pmonitor -> m_recvfd , F_SETFD , FD_CLOEXEC );
805
- fcntl (pmonitor -> m_log_sendfd , F_SETFD , FD_CLOEXEC );
806
-
807
- /*
808
- * Arrange unpriv-preauth child process fds:
809
- * 0, 1 network socket
810
- * 2 optional stderr
811
- * 3 reserved
812
- * 4 monitor message socket
813
- * 5 monitor logging socket
814
- *
815
- * We know that the monitor sockets will have fds > 4 because
816
- * of the reserved fds in main()
817
- */
818
-
819
- if (ssh_packet_get_connection_in (ssh ) != STDIN_FILENO &&
820
- dup2 (ssh_packet_get_connection_in (ssh ), STDIN_FILENO ) == -1 )
821
- fatal ("dup2 stdin failed: %s" , strerror (errno ));
822
- if (ssh_packet_get_connection_out (ssh ) != STDOUT_FILENO &&
823
- dup2 (ssh_packet_get_connection_out (ssh ),
824
- STDOUT_FILENO ) == -1 )
825
- fatal ("dup2 stdout failed: %s" , strerror (errno ));
826
- /* leave stderr as-is */
827
- log_redirect_stderr_to (NULL ); /* dup can clobber log fd */
828
- if (pmonitor -> m_recvfd != PRIVSEP_MONITOR_FD &&
829
- dup2 (pmonitor -> m_recvfd , PRIVSEP_MONITOR_FD ) == -1 )
830
- fatal ("dup2 monitor fd: %s" , strerror (errno ));
831
- if (pmonitor -> m_log_sendfd != PRIVSEP_LOG_FD &&
832
- dup2 (pmonitor -> m_log_sendfd , PRIVSEP_LOG_FD ) == -1 )
833
- fatal ("dup2 log fd: %s" , strerror (errno ));
834
- closefrom (PRIVSEP_MIN_FREE_FD );
835
-
836
- posix_spawn_file_actions_t actions ;
837
- posix_spawnattr_t attributes ;
838
- if (posix_spawn_file_actions_init (& actions ) != 0 ||
839
- posix_spawn_file_actions_adddup2 (& actions , io_sock_in , STDIN_FILENO ) != 0 ||
840
- posix_spawn_file_actions_adddup2 (& actions , io_sock_out , STDOUT_FILENO ) != 0 ||
841
- posix_spawn_file_actions_adddup2 (& actions , pmonitor -> m_recvfd , PRIVSEP_MONITOR_FD ) != 0 ||
842
- posix_spawn_file_actions_adddup2 (& actions , pmonitor -> m_log_sendfd , PRIVSEP_LOG_FD ) != 0 )
843
- fatal ("posix_spawn initialization failed" );
844
- else {
845
- pid_t pid ;
846
- if (posix_spawn (& pid , options .sshd_auth_path , & actions , & attributes , saved_argv , NULL ) != 0 )
847
- error ("%s, posix_spawn failed" , __func__ );
848
- posix_spawn_file_actions_destroy (& actions );
849
- posix_spawnattr_destroy (& attributes );
850
- }
851
- }
852
685
else { /* parent */
853
686
posix_spawn_file_actions_t actions ;
854
687
@@ -859,8 +692,6 @@ privsep_preauth(struct ssh *ssh)
859
692
posix_spawn_file_actions_adddup2 (& actions , pmonitor -> m_log_sendfd , PRIVSEP_LOG_FD ) != 0 )
860
693
fatal ("posix_spawn initialization failed" );
861
694
862
- //char** argv = privsep_child_cmdline(0);
863
- // if (__posix_spawn_asuser(&pid, argv[0], &actions, NULL, argv, NULL, SSH_PRIVSEP_USER) != 0)
864
695
if (__posix_spawn_asuser (& pid , options .sshd_auth_path , & actions , NULL , saved_argv , NULL , SSH_PRIVSEP_USER ) != 0 )
865
696
fatal ("%s, fork of unprivileged child failed" , __func__ );
866
697
@@ -880,8 +711,6 @@ privsep_preauth(struct ssh *ssh)
880
711
881
712
close (pmonitor -> m_recvfd );
882
713
close (pmonitor -> m_log_sendfd );
883
- //send_config_state(pmonitor->m_sendfd, cfg);
884
- //send_idexch_state(ssh, pmonitor->m_sendfd);
885
714
monitor_child_preauth (ssh , pmonitor );
886
715
while (waitpid (pid , & status , 0 ) < 0 ) {
887
716
if (errno == EINTR )
@@ -1006,13 +835,12 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
1006
835
posix_spawn_file_actions_adddup2 (& actions , pmonitor -> m_recvfd , PRIVSEP_MONITOR_FD ) != 0 )
1007
836
fatal ("posix_spawn initialization failed" );
1008
837
1009
- char * * argv = privsep_child_cmdline (1 );
838
+ char * * argv = privsep_child_cmdline ();
1010
839
if (__posix_spawn_asuser (& pmonitor -> m_pid , argv [0 ], & actions , NULL , argv , NULL , authctxt -> pw -> pw_name ) != 0 )
1011
840
fatal ("fork of unprivileged child failed" );
1012
841
posix_spawn_file_actions_destroy (& actions );
1013
842
1014
843
verbose ("User child is on pid %ld" , (long )pmonitor -> m_pid );
1015
- //sshbuf_reset(loginmsg);
1016
844
send_config_state (pmonitor -> m_sendfd , cfg );
1017
845
send_idexch_state (ssh , pmonitor -> m_sendfd );
1018
846
send_autxctx_state (authctxt , pmonitor -> m_sendfd );
@@ -1609,10 +1437,6 @@ main(int ac, char **av)
1609
1437
SSH_RELEASE , SSH_OPENSSL_VERSION );
1610
1438
exit (0 );
1611
1439
#ifdef WINDOWS
1612
- case 'y' :
1613
- privsep_unauth_child = 1 ;
1614
- logfile = NULL ;
1615
- break ;
1616
1440
case 'z' :
1617
1441
privsep_auth_child = 1 ;
1618
1442
logfile = NULL ;
@@ -1631,15 +1455,13 @@ main(int ac, char **av)
1631
1455
}
1632
1456
1633
1457
#ifdef WINDOWS
1634
- if (!rexeced_flag && !privsep_unauth_child && ! privsep_auth_child )
1458
+ if (!rexeced_flag && !privsep_auth_child )
1635
1459
#else /* WINDOWS */
1636
1460
if (!rexeced_flag )
1637
1461
#endif /* WINDOWS */
1638
1462
fatal ("sshd-session should not be executed directly" );
1639
1463
#ifdef WINDOWS
1640
- if (privsep_unauth_child )
1641
- closefrom (PRIVSEP_UNAUTH_MIN_FREE_FD );
1642
- else if (privsep_auth_child )
1464
+ if (privsep_auth_child )
1643
1465
closefrom (PRIVSEP_AUTH_MIN_FREE_FD );
1644
1466
else
1645
1467
closefrom (REEXEC_MIN_FREE_FD );
@@ -1688,7 +1510,7 @@ main(int ac, char **av)
1688
1510
fatal ("sshbuf_new config buf failed" );
1689
1511
setproctitle ("%s" , "[rexeced]" );
1690
1512
#ifdef WINDOWS
1691
- if (privsep_unauth_child || privsep_auth_child ) {
1513
+ if (privsep_auth_child ) {
1692
1514
recv_rexec_state (PRIVSEP_MONITOR_FD , cfg , & timing_secret ); //TODO - should starup_pipe be closed as above ?B
1693
1515
}
1694
1516
else {
@@ -1722,7 +1544,7 @@ main(int ac, char **av)
1722
1544
endpwent ();
1723
1545
1724
1546
#ifdef WINDOWS
1725
- if (!debug_flag && !inetd_flag && !privsep_unauth_child && ! privsep_auth_child ) {
1547
+ if (!debug_flag && !inetd_flag && !privsep_auth_child ) {
1726
1548
#else /* WINDOWS */
1727
1549
if (!debug_flag && !inetd_flag ) {
1728
1550
#endif /* WINDOWS */
@@ -1910,7 +1732,7 @@ main(int ac, char **av)
1910
1732
1911
1733
rdomain = ssh_packet_rdomain_in (ssh );
1912
1734
1913
- if (privsep_unauth_child || privsep_auth_child ) {
1735
+ if (privsep_auth_child ) {
1914
1736
recv_idexch_state (ssh , PRIVSEP_MONITOR_FD );
1915
1737
goto idexch_done ;
1916
1738
}
0 commit comments