171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
pclose2(sshIn, sshOut, sshPid);
fossil_fatal("ssh connection failed: [%s]", zIn);
}
fossil_free(zIn);
}
/*
** Global initialization of the transport layer
*/
void transport_global_startup(void){
if( g.urlIsSsh ){
/* Only SSH requires a global initialization. For SSH we need to create
** and run an SSH command to talk to the remote machine.
*/
const char *zSsh; /* The base SSH command */
Blob zCmd; /* The SSH command */
char *zHost; /* The host name to contact */
int n; /* Size of prefix string */
zSsh = db_get("ssh-command", zDefaultSshCmd);
blob_init(&zCmd, zSsh, -1);
if( g.urlPort!=g.urlDfltPort ){
#ifdef __MINGW32__
blob_appendf(&zCmd, " -P %d", g.urlPort);
#else
blob_appendf(&zCmd, " -p %d", g.urlPort);
#endif
}
fossil_force_newline();
fossil_print("%s", blob_str(&zCmd)); /* Show the base of the SSH command */
if( g.urlUser && g.urlUser[0] ){
zHost = mprintf("%s@%s", g.urlUser, g.urlName);
#ifdef __MINGW32__
/* Only win32 (and specifically PLINK.EXE) support the -pw option */
if( g.urlPasswd && g.urlPasswd[0] ){
Blob pw;
blob_zero(&pw);
if( g.urlPasswd[0]=='*' ){
char *zPrompt;
zPrompt = mprintf("Password for [%s]: ", zHost);
prompt_for_password(zPrompt, &pw, 0);
free(zPrompt);
}else{
blob_init(&pw, g.urlPasswd, -1);
}
blob_append(&zCmd, " -pw ", -1);
shell_escape(&zCmd, blob_str(&pw));
blob_reset(&pw);
fossil_print(" -pw ********"); /* Do not show the password text */
}
#endif
}else{
zHost = mprintf("%s", g.urlName);
}
n = blob_size(&zCmd);
blob_append(&zCmd, " ", 1);
shell_escape(&zCmd, zHost);
if( g.urlShell ){
blob_appendf(&zCmd, " %s", g.urlShell);
}else{
#if defined(FOSSIL_ENABLE_SSH_FAR_SIDE)
/* The following works. But only if the fossil on the remote side
** is recent enough to support the test-ssh-far-side command. That
** command was added on 2013-02-06. We will leave this turned off
** until most fossil servers have upgraded to that version or a later
** version. The sync will still work as long as the shell on the far
** side is bash and not tcsh. And if the default far side shell is
** tcsh, then the shell=/bin/bash query parameter can be used as a
** work-around. Enable this code after about a year...
*/
blob_appendf(&zCmd, " exec %s test-ssh-far-side", g.urlFossil);
#endif
}
fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */
free(zHost);
popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
if( sshPid==0 ){
fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
}
blob_reset(&zCmd);
transport_ssh_startup();
}
}
/*
** COMMAND: test-ssh-far-side
**
** Read lines of input text, one by one, and evaluate each line using
** system(). The ssh: sync protocol uses this on the far side of the
|
|
|
<
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
|
|
<
<
<
<
|
<
<
<
|
|
>
>
>
|
|
|
|
|
|
|
>
>
|
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
pclose2(sshIn, sshOut, sshPid);
fossil_fatal("ssh connection failed: [%s]", zIn);
}
fossil_free(zIn);
}
/*
** SSH initialization of the transport layer
*/
int transport_ssh_open(void){
/* For SSH we need to create and run an SSH http
** to talk to the remote machine.
*/
const char *zSsh; /* The base SSH command */
Blob zCmd; /* The SSH command */
char *zHost; /* The host name to contact */
char *zPath; /* The path to the remote file for SSH */
int n; /* Size of prefix string */
zSsh = db_get("ssh-command", zDefaultSshCmd);
blob_init(&zCmd, zSsh, -1);
if( g.urlPort!=g.urlDfltPort ){
#ifdef __MINGW32__
blob_appendf(&zCmd, " -P %d", g.urlPort);
#else
blob_appendf(&zCmd, " -p %d", g.urlPort);
#endif
}
fossil_force_newline();
fossil_print("%s", blob_str(&zCmd)); /* Show the base of the SSH command */
if( g.urlUser && g.urlUser[0] ){
zHost = mprintf("%s@%s", g.urlUser, g.urlName);
#ifdef __MINGW32__
/* Only win32 (and specifically PLINK.EXE) support the -pw option */
if( g.urlPasswd && g.urlPasswd[0] ){
Blob pw;
blob_zero(&pw);
if( g.urlPasswd[0]=='*' ){
char *zPrompt;
zPrompt = mprintf("Password for [%s]: ", zHost);
prompt_for_password(zPrompt, &pw, 0);
free(zPrompt);
}else{
blob_init(&pw, g.urlPasswd, -1);
}
blob_append(&zCmd, " -pw ", -1);
shell_escape(&zCmd, blob_str(&pw));
blob_reset(&pw);
fossil_print(" -pw ********"); /* Do not show the password text */
}
#endif
}else{
zHost = mprintf("%s", g.urlName);
}
n = blob_size(&zCmd);
blob_append(&zCmd, " ", 1);
shell_escape(&zCmd, zHost);
if( g.urlShell ){
blob_appendf(&zCmd, " %s", g.urlShell);
}
if( g.fSshFossilCmd && g.fSshFossilCmd[0] ){
blob_append(&zCmd, " ", 1);
shell_escape(&zCmd, g.fSshFossilCmd);
blob_appendf(&zCmd, " %s ", g.fSshHttpCmd);
if( g.urlPath && g.urlPath[0] ){
zPath = mprintf("%s", g.urlPath);
shell_escape(&zCmd, zPath);
}
}
fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */
free(zHost);
popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
if( sshPid==0 ){
socket_set_errmsg("cannot start ssh tunnel using [%b]", &zCmd);
}
blob_reset(&zCmd);
if( g.fSshFossilCmd==0 ){
transport_ssh_startup();
}
return sshPid==0;
}
/*
** COMMAND: test-ssh-far-side
**
** Read lines of input text, one by one, and evaluate each line using
** system(). The ssh: sync protocol uses this on the far side of the
|
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
|
** g.urlIsHttps Use TLS for the connection
**
** Return the number of errors.
*/
int transport_open(void){
int rc = 0;
if( transport.isOpen==0 ){
if( g.urlIsSsh ){
Blob cmd;
blob_zero(&cmd);
shell_escape(&cmd, g.urlFossil);
blob_append(&cmd, " test-http ", -1);
shell_escape(&cmd, g.urlPath);
fprintf(sshOut, "%s || true\n", blob_str(&cmd));
fflush(sshOut);
|
|
>
>
>
>
>
>
|
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
|
** g.urlIsHttps Use TLS for the connection
**
** Return the number of errors.
*/
int transport_open(void){
int rc = 0;
if( transport.isOpen==0 ){
if( g.urlIsSsh && g.fSshFossilCmd ){
rc = transport_ssh_open();
if( rc==0 ) transport.isOpen = 1;
}else if( g.urlIsSsh ){
if( sshPid==0 ){
rc = transport_ssh_open();
}
Blob cmd;
blob_zero(&cmd);
shell_escape(&cmd, g.urlFossil);
blob_append(&cmd, " test-http ", -1);
shell_escape(&cmd, g.urlPath);
fprintf(sshOut, "%s || true\n", blob_str(&cmd));
fflush(sshOut);
|
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
|
i++;
}
if( g.fSshTrace ) printf("Got line: [%s]\n", &transport.pBuf[iStart]);
return &transport.pBuf[iStart];
}
void transport_global_shutdown(void){
if( g.urlIsSsh && sshPid ){
/*printf("Closing SSH tunnel: ");*/
fflush(stdout);
pclose2(sshIn, sshOut, sshPid);
sshPid = 0;
}
if( g.urlIsHttps ){
#ifdef FOSSIL_ENABLE_SSL
ssl_global_shutdown();
#endif
}else{
socket_global_shutdown();
}
}
|
<
<
<
|
<
<
>
>
>
>
>
>
>
>
>
|
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
|
i++;
}
if( g.fSshTrace ) printf("Got line: [%s]\n", &transport.pBuf[iStart]);
return &transport.pBuf[iStart];
}
void transport_global_shutdown(void){
transport_ssh_close();
if( g.urlIsHttps ){
#ifdef FOSSIL_ENABLE_SSL
ssl_global_shutdown();
#endif
}else{
socket_global_shutdown();
}
}
void transport_ssh_close(void){
if( g.urlIsSsh && sshPid ){
/*printf("Closing SSH tunnel: ");*/
fflush(stdout);
pclose2(sshIn, sshOut, sshPid);
sshPid = 0;
}
}
|